$(document).ready(function(){
	$('[placeholder]').placeholderInput();
	$('.bl-hd-nav dd, .pg-nav ul.bl-links li').userMenu();
	$('.bl-fm-info .bl-fm-submit > div').otherMenu();
	$('.pg-head').headerMove();
	$('.bl-ls-side dl, .bl-lg-info dl, .bl-fm-change dl').accordWithIcon();
	$('input[type="checkbox"], input[type="radio"], select').emulationInput();
	$('input.inp-date').datePicker();
	$('.pg-ls-rth').actionTable();
	$('.un-ds-txt').accordWithIcon({headElement:'h3.accord', bodyElement:'.e-accord-txt'});
	$('a.help').aTooltip({xOffset:18, yOffset:16});
	$('.bl-ds-scroll').scrollTable();
	$('.bl-fm-tabs, .bl-hm-tabs').tabsContent();
	$('.bl-fm-calc, .bl-ts-def').actionForm();
	$('.pg-def').printEdit();
	$('.bl-rp-list article').accordWithIcon({headElement:'.line-ac', bodyElement:'.e-accord-txt', innerElement:'.accord'});
});

if(jQuery) (function($){
	//
	$.fn.hoverIntent = function (f, g) {
    var cfg = {
      sensitivity: 7,
      interval: 100,
      timeout: 0
    };
    cfg = $.extend(cfg, g ? {
      over: f,
      out: g
    } : f);
    var cX, cY, pX, pY;
    var track = function (ev) {
        cX = ev.pageX;
        cY = ev.pageY
      };
    var compare = function (ev, ob) {
        ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
        if ((Math.abs(pX - cX) + Math.abs(pY - cY)) < cfg.sensitivity) {
          $(ob).unbind("mousemove", track);
          ob.hoverIntent_s = 1;
          return cfg.over.apply(ob, [ev])
        } else {
          pX = cX;
          pY = cY;
          ob.hoverIntent_t = setTimeout(function () {
            compare(ev, ob)
          }, cfg.interval)
        }
      };
    var delay = function (ev, ob) {
        ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t);
        ob.hoverIntent_s = 0;
        return cfg.out.apply(ob, [ev])
      };
    var handleHover = function (e) {
        var ev = jQuery.extend({}, e);
        var ob = this;
        if (ob.hoverIntent_t) {
          ob.hoverIntent_t = clearTimeout(ob.hoverIntent_t)
        }
        if (e.type == "mouseenter") {
          pX = ev.pageX;
          pY = ev.pageY;
          $(ob).bind("mousemove", track);
          if (ob.hoverIntent_s != 1) {
            ob.hoverIntent_t = setTimeout(function () {
              compare(ev, ob)
            }, cfg.interval)
          }
        } else {
          $(ob).unbind("mousemove", track);
          if (ob.hoverIntent_s == 1) {
            ob.hoverIntent_t = setTimeout(function () {
              delay(ev, ob)
            }, cfg.timeout)
          }
        }
      };
    return this.bind('mouseenter', handleHover).bind('mouseleave', handleHover)
  };
	//
	$.fn.tabsContent = function(params){
		var conf = $.extend({
			headerElement:'.head li'
		}, params);
		return this.each(function(){
			var c=conf,$o=$(this),f=this,$eh=$o.find(c.headerElement),d=null, bh=null;
			$.extend(f,{
				_changeElement:function(element, prev_element){
					var e_i=f._innerLink(element, 'a'), prev_e_i=f._innerLink(prev_element, 'span');
					d=element;
					if(prev_e_i){
						prev_e_i.replaceWith(
							$('<a />').html(prev_e_i.html()).attr({'title':prev_e_i.attr('title'),'href':bh})
						);
						$o.find(bh).hide()
						f._innerLink(prev_element, 'a').bind('click', function(){
							f._changeElement(prev_element, d);
							return false;
						})
					}
					bh=e_i.attr('href');
					e_i.replaceWith(
						$('<span />').html(e_i.html()).attr({'title':e_i.attr('title')})
					);$o.find(bh).show()
				},
				_innerLink:function(element, type){
					if(element) return element.children(type);
					else return false;
				}
			});
			if($o.hasClass('js-no-tabs')) return true;
			$eh.each(function(i){
				var e=$(this), el=f._innerLink(e, 'a');
				if($o.find(el.attr('href')).length > 0){
					$o.find(el.attr('href')).hide();
					el.bind('click', function(){
						f._changeElement(e, d);
						return false;
					})
				}
			})
			$eh.each(function(){
				if($(this).hasClass('active')) f._innerLink($(this), 'a').click();
			})
			//$eh.hasClass('active')
			//alert($eh.eq($(this).hasClass('active')))
			//f._innerLink($eh.eq(c.openItem), 'a').click();
		})
	};
	//
	$.fn.headerMove = function(params){
		var conf = $.extend({
			moveClass:'pg-head-move',
			absClass:'pg-head-abs'
		}, params);
		return this.each(function(){
			var $o=$(this), f=this, $w=$(window), o_height=$o.innerHeight(), c=conf;
			$.extend(f,{
				_move:function(){
					if($w.scrollTop()>=o_height){
						$o.addClass(c.moveClass);
						$o.css('marginTop',$w.scrollTop())
					}else{
						$o.removeClass(c.moveClass)
						$o.css('marginTop',0)
					}
				}
			})
			if(!$o.hasClass('pg-head-static')){
				$o.addClass(c.absClass).before($('<div class="pg-head-em"></div>').css({height:o_height}));
				$o.find('.el-nav-top a').on('click', function(){
					$('html, body').animate({scrollTop:0});
					return false;
				})
				$w.on('load resize scroll', function(){
					f._move();
				});
			}
		});
	};
	//
	$.fn.userMenu = function(params){
		var conf=$.extend({
			activeClass:'hover'
		}, params);
		return this.each(function(){
			var	c=conf, $i_o=$('a', $(this));
			$i_o.each(function(){
				var $i=$(this), $p=$i.parent(), $b=$i.next();
				if($b.length){
					$b.addClass('hide');
					$p.hoverIntent({
						timeout:150,
						over:function(){
							$b.removeClass('hide');
							$i.addClass(c.activeClass)
						},
						out:function(){
							$b.addClass('hide');
							$i.removeClass(c.activeClass)
						}
					})
				}
			})
		})
	};
	//
	$.fn.otherMenu = function(params){
		var conf=$.extend({
			activeClass:'hover'
		}, params);
		return this.each(function(){
			var	c=conf, $i_o=$('a', $(this)); 
			$i_o.each(function(){
				var $i=$(this), $p=$i.parent(), $b=$i.next();
				if($b.length){
					$p.addClass('other-menu-click')
					//$b.css({left:$i.position().left});
					$(document).on('click', function(e){
						if(!$(e.target).parent().hasClass('other-menu-click')){
							$b.addClass('hide');
							$i.removeClass(c.activeClass)
						}
					});
					$b.addClass('hide');
					$i.on('click', function(e){
						if($b.hasClass('hide')){
							$b.removeClass('hide');
							$i.addClass(c.activeClass)
						}else{
							$b.addClass('hide');
							$i.removeClass(c.activeClass)
						}
						e.preventDefault();;
					})
				}
			})
		})
	};
	//
	$.fn.accordWithIcon = function(params){
		var conf = $.extend({
			headElement:'dt',
			bodyElement:'dd',
			innerElement:null
		}, params);
		return this.each(function(){
			var c=conf, $o=$(this);
			$o.children().each(function(){
				if($(this).is(c.headElement)){
					if($(this).next().is(c.bodyElement)){
						var $h=c.innerElement?$(this).find(c.innerElement):$(this), $b=$(this).next(), b_height=$b.css('maxHeight');
						if(b_height!='none'){
							if($b.height()>b_height){$b.height(b_height)}
						}
						$b.hide();
						if($b.html()!=''){
							var $i=$('<span class="icon">+</span>'), $l=$('<a href="#"></a>').html($h.html()), $c=$h;
							$h.empty().append($i).append($l).addClass('close');
							$l.bind('click', function(e){
								$i.trigger('click');
								e.preventDefault();
							});
							$i.bind('click', function(){
								if($h.hasClass('close')){
									$b.stop().slideDown();
									if($h.hasClass('slide')){
										$h.stop().slideUp();
									}
									$c.removeClass('close');
									$i.html('-');
								}else{
									$b.stop().slideUp();
									$c.addClass('close');
									$i.html('+');
								}
							});
						}
						if($h.hasClass('open')){
							$b.show();
							if($c.hasClass('slide')){
								$c.hide();
							}
							$c.removeClass('close').removeClass('open');
							$i.html('-');
						}
					}
				}
			})
		})
	};
	//
	$.fn.placeholderInput = function(params){
		var conf=$.extend({
			classDef:'holder'
		}, params);
		return this.each(function(){
			var f=this;
			if(f.placeholder && 'placeholder' in document.createElement(f.tagName)) return;
			var $o=$(this), c=conf, placeholder=f.getAttribute('placeholder');
			if(f.value === '' || f.value == placeholder){
				$o.addClass(c.classDef);
				f.value=placeholder;
			}
			$o.on('focus', function(){
				if($o.hasClass(c.classDef)){
					this.value='';
					$o.removeClass(c.classDef)
				}
			}).on('blur', function(){
				if(this.value === ''){
					$o.addClass(c.classDef);
					this.value=placeholder;
				}else{
					$o.removeClass(c.classDef);
				}
			});
			f.form && $(f.form).submit(function(){
				if($o.hasClass(c.classDef)){
					that.value='';
				}
			});
		})
	};
	// need fixed
	$.fn.aModal = function(params){
		 var conf=$.extend({
			modalCustom:null,
			ifClick:true
		}, params);
		return this.each(function(){
			var $o=$(this), f=this, c=conf, $m;
			if(c.modalCustom){
				$m=$(c.modalCustom);
			}else if(f.hash!=undefined && $(f.hash).length){
				$m=$(f.hash);
			}else{return true}
			var $m_o=$('<div class="pg-modal-overlay"></div>'), $m_c=$('<a class="close" href="#" title="Sluiten">Sluiten</a>'), m_w, m_h;
			$.extend(f,{
				_build:function(){
					$m.append($m_c);
				},
				_show:function(){
					$('body').append($m_o);
					if(c.ifClick){
						$m_o.on('click', function(){f._hide()});
					}
					$m.css({display:'block', position:'fixed', zIndex:11000, top:'-999em', left:'-999em'});
					m_w=$m.innerWidth(), m_h=$m.innerHeight();
					$m_o.fadeTo(200, 1);
					$m.css({opacity:0, left:'50%', marginLeft:-(m_w/2), top:($(window).height()/2)-m_h}).fadeTo(200, 1);
				},
				_hide:function(){
				  $m_o.fadeTo(200, 0, function(){$m_o.remove()});
					$m.fadeTo(200, 0, function(){$m.hide()});
				}
			});
			f._build()
			$('.close, .btn a', $m).on('click', function(e){
				f._hide();
				e.preventDefault();
			})
			$o.on('click', function(e){
				f._show();
				e.preventDefault();
			});
		});
  };
	//
	$.fn.aTooltip = function(params){
		 var conf=$.extend({
			tipClass:'bl-tip',
			modalCustom:null,
			tipCustom:null,
			xOffset:18,
			yOffset:16
		}, params);
		var $m_o=$('<div class="pg-modal-overlay"></div>');
		$('body').append($m_o);
		return this.each(function(){
			var $o=$(this), f=this, c=conf, $t, $m;
			$.extend(f,{
				_init_tip:function(){
					var $t_a=$('<span class="arrow"></span>'), $t_c=$('<a class="close" href="#" title="Sluiten">Sluiten</a>');
					if(c.tipCustom){
						$t=$(c.tipCustom);
					}else if(f.hash!=undefined && $(f.hash).length){
						$t=$(f.hash);
					}else{return true}
					$('body').append($t.hide());
					if(!$t.find('.arrow').length) $t.append($t_a);
					if(!$t.find('.close').length) $t.append($t_c);
					$o.on('click',function(e){
						$('.'+c.tipClass).hide();
						if($t.find('.edit').length) f._init_modal($t.find('.edit'));
						f._position_tip();
						$(window).on('tooltip.move', function(){f._position_tip()});
						$t.show().find('.close').on('click', function(e_i){
							$(window).off('tooltip.move');
							$t.hide();
							e_i.preventDefault();
						}).find('.edit').on('click', function(e_i){
							$t.hide();
							e_i.preventDefault();
						});
						e.preventDefault();
					});
					$(window).on('resize scroll', function(){$(this).trigger('tooltip.move')})
				},
				_init_modal:function($l){
					if($m==undefined){
						var $m_c=$('<a class="close" href="#" title="Sluiten">Sluiten</a>');
						if(c.modalCustom){
							$m=$(c.modalCustom);
						}else if($l[0].hash!=undefined && $($l[0].hash).length){
							$m=$($l[0].hash);
						}else{return true}
						if(!$m.find('.close').length) $m.append($m_c);
						$('body').append($m);
					}
					$l.on('click', function(e){
						if($o!==$l){
							$t.hide();
						}
						$m.css({display:'block', position:'fixed', zIndex:11000, top:'-999em', left:'-999em'});
						$('textarea', $m).xheditor({tools:'Bold,Italic,Underline,|,List,|,Link,Img'});
						$m_o.fadeTo(200, 1);
						$m.css({opacity:0, left:'50%', marginLeft:-($m.innerWidth()/2), top:($(window).height()/2)-$m.innerHeight()}).fadeTo(200, 1);
						e.preventDefault();
						$m.find('.link a, .close').on('click', function(e_i){
							$m.fadeTo(200, 0, function(){$('textarea', $m).xheditor(false); $m.hide()});
							$m_o.fadeTo(200, 0, function(){$m_o.hide()});
							e_i.preventDefault();
						});
					});
				},
				_position_tip:function(){
					var o_p=$o.offset(), $w=$(window), t_p=$w.width()-$o.width()-($o.offset().left-$w.scrollLeft())-($t.innerWidth()+20);
					if(t_p>0){
						$t.css({
							top:(o_p.top-c.yOffset),
							left:(o_p.left+($o.outerWidth())+c.xOffset)
						});
						$t.find('.arrow').removeClass('arrow-left').addClass('arrow-right');
					}else{
						$t.css({
							top:(o_p.top-c.yOffset),
							left:(o_p.left-$t.innerWidth()-($o.outerWidth())-c.xOffset)
						});
						$t.find('.arrow').removeClass('arrow-right').addClass('arrow-left');
					}
				}
			});
			if($o.hasClass('help-hide')){
				f._init_modal($o)
			}else{
				f._init_tip()
			}
		});
  };
	//
	$.fn.emulationInput = function(params){
		var conf = $.extend({
			extendId:'-emul',
			sPosition:true,
			vOptions:0,
			checkboxClass:'el-btn-chk',
			radioClass:'el-btn-rdo'
		}, params);
		return this.each(function(){
			var $o=$(this), f=this, c=conf, o_id='', o_class='', o_title='', o_data='';
			if($o.prop('id')!==undefined && $o.prop('id')!='') o_id=' id="'+$o.prop('id')+ c.extendId + '"';
			if($o.prop('class')!==undefined && $o.prop('class')!='') o_class=' '+$o.prop('class');
			if($o.prop('title')!==undefined && $o.prop('title')!='') o_title=' title="'+$o.prop('title')+'"';
			/*var data=$o.data();
			for(var i in data){if(data[i]!='') o_data+=' data-'+i+'="'+data[i]+'"';}
			o_id += o_data;*/
			$.extend(f,{
				_checkbox:function(){
					$o.css({position:'absolute', left:-9999}).each(function(){
						if($o.next('span.bx-checkbox').length<1){
							var $w=$('<span'+o_id+' class="bx-checkbox'+o_class+'"'+o_title+' style="display:inline-block"><span></span></span>');
							$o.after($w);
							if($o.is(':checked')) $w.addClass('on');
							if($o.is(':disabled')) $w.addClass('disabled');
							$w.on('click', function(e){
								if(!$w.is('.disabled')){
									if($o.is(':checked')){
										$o.prop('checked', false);
										$w.removeClass('on');
									}else{
										$o.prop('checked', true);
										$w.addClass('on');
									}
									$o.change();
									e.preventDefault(e);
								}else{return false}
							});
							$o.parent('label').add('label[for="'+$o.prop('id')+'"]').on('click', function(e){
								$w.click();
								e.preventDefault();
							});
							$o.on('change', function(){
								if($o.is(':checked')) $w.addClass('on');
								else $w.removeClass('on');
							}).on('keydown', function(e){
								if($o.parent('label').length && (e.which == 13 || e.which == 32)) $w.click();
							}).on('focus', function(){
								if(!$w.is('.disabled')) $w.addClass('focused');
							}).on('blur', function(){
								$w.removeClass('focused');
							}).on('refresh', function(){
								if($o.is(':checked')) $w.addClass('on');
								else $w.removeClass('on');
								if($o.is(':disabled')) $w.addClass('disabled');
								else $w.removeClass('disabled');
							});
						}
					})
				},
				_radio:function(){
					$o.css({position:'absolute', left:-9999}).each(function(){
						if($o.next('span.bx-radio').length < 1){
							var $w=$('<span'+o_id+' class="bx-radio'+o_class+'"'+o_title+' style="display:inline-block"><span></span></span>');
							$o.after($w);
							if($o.is(':checked')) $w.addClass('on');
							if($o.is(':disabled')) $w.addClass('disabled');
							$w.on('click', function(e){
								if(!$w.is('.disabled')){
									$w.closest('form').find('input[name="'+$o.prop('name')+'"]').prop('checked', false).next().removeClass('on');
									$o.prop('checked', true).next().addClass('on');
									$o.change();
									e.preventDefault(e);
								}else{return false}
							});
							$o.parent('label').add('label[for="'+ $o.prop('id')+'"]').on('click', function(e){
								$w.click();
								e.preventDefault();
							});
							$o.on('change', function(){
								$('input[name="'+$o.prop('name')+'"]').next().removeClass('on');
								$o.next().addClass('on');
							}).on('focus', function(){
								if(!$w.is('.disabled')) $w.addClass('focused');
							}).on('blur', function(){
								$w.removeClass('focused');
							}).on('refresh', function(){
								if($o.is(':checked')){
									$('input[name="'+$o.prop('name')+'"]').next().removeClass('on');
									$w.addClass('on');
								}else radio.removeClass('on');
								if($o.is(':disabled')) $w.addClass('disabled');
								else $w.removeClass('disabled');
							});
						}
					});
				},
				_select:function(){
					$o.each(function(){
						if($o.next('span.bx-select').length<1){
							if($o.is('[multiple]')) f._multi($o_option); else f._single($o_option);
						}
					});
				},
				_list:function(){
					for(i = 0, len=$o_option.length; i<len; i++){
						var $l_li='', l_class='', l_option_class='', l_optgroup_class='', l_disabled='disabled', l_sel_disabled='selected sel disabled';
						if($o_option.eq(i).prop('selected')) l_class='selected sel';
						if($o_option.eq(i).is(':disabled')) l_class=disabled;
						if($o_option.eq(i).is(':selected:disabled')) l_class=l_sel_disabled;
						if($o_option.eq(i).prop('class')!==undefined) l_option_class=' '+$o_option.eq(i).prop('class');
						$l_li='<li class="'+l_class+l_option_class+'">'+$o_option.eq(i).text()+'</li>';
						if($o_option.eq(i).parent().is('optgroup')){
							if($o_option.eq(i).parent().prop('class')!==undefined) l_optgroup_class=' '+$o_option.eq(i).parent().prop('class');
							$l_li='<li class="'+l_class+l_option_class+' option'+l_optgroup_class+'">'+$o_option.eq(i).text()+'</li>';
							if($o_option.eq(i).is(':first-child')){
								$l_li='<li class="optgroup'+l_optgroup_class+'">'+$o_option.eq(i).parent().prop('label')+'</li>'+$l_li;
							}
						}
						o_list+=$l_li;
						
					}
				},
				_multi:function(){
					alert('not used')
				},
				_single:function(){
					var $w=$('<span'+o_id+' class="bx-select'+o_class+'" style="display:inline-block; position:relative; z-index:'+c.singleSelectzIndex+'">'+
							'<div class="bx-select-view"'+o_title+'>'+
								'<div class="bx-select-text"></div>'+
								'<div class="arrow"></div>'+
							'</div>'+
						'</span>');
					$o.after($w).css({position:'absolute', left:-9999});
					var $w_view=$('div.bx-select-view', $w), $w_text=$('div.bx-select-text', $w), $w_active = $o_option.filter(':selected'), w_class=$o_option.filter(':selected').prop('class');
					if($w_active.length){
						$w_text.text($w_active.text());
						$w_view.addClass(w_class);
					}else{
						$w_text.text($o_option.first().text());
						$w_view.addClass($o_option.first().prop('class'))
					}
					
					if($o.is(':disabled')){
						$w.addClass('disabled');
					}else{
						f._list();
						var $d=$('<div class="bx-select-dropdown" style="position:absolute; overflow:auto; overflow-x:hidden">'+
							'<ul style="list-style:none">'+o_list+'</ul>'+
						'</div>');
						$w.append($d);
						var $li=$('li', $d);
						if($li.filter('.selected').length < 1) $li.first().addClass('selected sel');
						var o_h=$w.outerHeight();
						if($d.css('left')=='auto') $d.css({left:0});
						if($d.css('top')=='auto') $d.css({top:o_h});
						var li_h=$li.outerHeight(), d_position=$d.css('top');
						$d.hide();
						$w_view.on('click', function(){
							$o.focus();
							if(c.sPosition){
								var $win=$(window), top_ff=$w.offset().top, bottom_ff=$win.height()-o_h-(top_ff-$win.scrollTop()), visible=c.vOptions, min_h=li_h*6, new_h=li_h*visible;
								if(visible>0 && visible<6) min_h=new_h;
								
								if (bottom_ff<0 || bottom_ff<min_h){
									$d.height('auto').css({top:'auto', bottom:d_position});
									if($d.outerHeight()>top_ff-$win.scrollTop()-20){
										$d.height(Math.floor((top_ff-$win.scrollTop()-20) / li_h)*li_h);
										if(visible>0 && visible<6){
											if($d.height()>min_h) $d.height(min_h);
										}else if(visible>6){
											if($d.height()>new_h) $d.height(new_h);
										}
									}
								}else if(bottom_ff>min_h){
									$d.height('auto').css({bottom:'auto', top:d_position});
									if($d.outerHeight()>bottom_ff-20){
										$d.height(Math.floor((bottom_ff-20) / li_h)*li_h);
										if(visible>0 && visible <6){
											if($d.height()>min_h) $d.height(min_h);
										}else if(visible>6){
											if($d.height()>new_h) $d.height(new_h);
										}
									}
								}
							}
							$('span.bx-select').css({zIndex:600}).removeClass('focused');
							$w.css({zIndex:601});
							if($d.is(':hidden')){
								$('div.bx-select-dropdown:visible').hide();
								$d.show();
								$w.addClass('opened');
							}else{
								$d.hide();
								$w.removeClass('opened');
							}
							if($li.filter('.selected').length){
								$d.scrollTop($d.scrollTop()+$li.filter('.selected').position().top-$d.innerHeight()/2+li_h/2);
							}
							//preventScrolling($d);
							return false;
						});
						$li.hover(function(){
							$(this).siblings().removeClass('selected');
						});
						var selectedText=$li.filter('.selected').text();
						$li.filter(':not(.disabled):not(.optgroup)').on('click', function(){
							var $t=$(this), t_text=$t.text();
							if(selectedText!=t_text){
								var t_index=$t.index();
								if($t.is('.option')) t_index-=$t.prevAll('.optgroup').length;
								$t.addClass('selected sel').siblings().removeClass('selected sel');
								$o_option.prop('selected', false).eq(t_index).prop('selected', true);
								selectedText=t_text;
								$w_text.text(t_text);
								$o.change();
							}
							$d.hide();
						});
						$d.on('mouseout', function(){
							$('li.sel', $d).addClass('selected');
						});
						$o.on('change', function(){
							$w_text.text($o_option.filter(':selected').text());
							$w_view.removeClass(w_class);
							w_class=$o_option.filter(':selected').prop('class');
							$w_view.addClass(w_class);
							$li.removeClass('selected sel').not('.optgroup').eq($o[0].selectedIndex).addClass('selected sel');
						}).on('focus', function(){
							$w.addClass('focused');
						}).on('blur', function(){
							$w.removeClass('focused');
						}).on('keydown keyup', function(e){
							$w_text.text($o_option.filter(':selected').text());
							$li.removeClass('selected sel').not('.optgroup').eq($o[0].selectedIndex).addClass('selected sel');
							if(e.which==38 || e.which==37 || e.which==33){
								$d.scrollTop($d.scrollTop() + $li.filter('.selected').position().top);
							}
							if(e.which==40 || e.which==39 || e.which==34){
								$d.scrollTop($d.scrollTop()+$li.filter('.selected').position().top-$d.innerHeight()+li_h);
							}
							if(e.which==13){
								$d.hide();
							}
						});
						$(document).on('click', function(e){
							if(!$(e.target).parents().hasClass('selectbox') && e.target.nodeName!='OPTION'){
								$d.hide().find('li.sel').addClass('selected');
								$w.removeClass('focused opened');
							}
						});
					}
				}
			})
			if($o.is(':checkbox')){
				f._checkbox();
			}else if($o.is(':radio')){
				f._radio();
			}else if($o.is('select')){
				var $o_option=$('option', $o), o_list='';
				f._select();
				$o.on('refresh', function(){
					$o.next().remove(); $o_option=$('option', $o), o_list='';
					f._select();
				});
			}
			
		});
	};
	//
	$.fn.actionTable = function(params){
		var conf = $.extend({
			checkboxAll:'.bl-ls-action input[type="checkbox"]'
		}, params);
		return this.each(function(){
			var $o=$(this), c=conf, f=this, $t=$('table.bl-ls-table', $o), $o_f=$('tfoot', $t), state=0, $o_s=$('.bl-ls-action .size', $o), $o_r=$('.bl-ls-size span', $o), $o_a=$('.bl-ls-action .el-submit, .bl-ls-action .e-submit', $o), $m_bl=$('.bl-fm-ok', $o); // fix class
			if(!$t.length) return false;
			
			$.extend(f,{
				_size_show:function(arl){
					if(arl.length){$o_r.text('1-'+arl.length)}
				},
				_generate_tbl:function(o_j){
					var ls='', a=typeof o_j != 'object' ? JSON.parse(o_j):o_j;
					$.each(a, function(k, v){
						ls+='<tr>';
						$.each(v, function(i_k, i_v){
							if(Object.prototype.toString.call(i_v)==='[object Array]'){
								$.each(i_v, function(m_k, m_v){
									var $lsc='';
									if(m_v.element=='checkbox') $lsc='<input type="checkbox"'+(m_v.data_action?' data-action="'+m_v.data_action+'"':'')+' id="'+m_v.id+'" name="'+m_v.name+'" />';
									else if(m_v.content) $lsc=m_v.content;
									ls+='<td'+(m_v.class_name?' class="'+m_v.class_name+'"':'')+'>'+$lsc+'</td>';
								})
							}
						})
						ls+='</tr>';
					})
					return ls;
				},
				_ajax_tbl:function(){
					$o_f.find('.more a').on('click', function(e){
						$.ajax({
							url:$o_f.find('.more a').prop('href'),
							dataType:'json',
							beforeSend:function(){
								$o_f.hide();
							},
							error:function(){},
							success:function(d){
								$('tbody', $t).append(f._generate_tbl(d.data));
								var ar=$('input[type="checkbox"]', $t), f_ar=$(c.checkboxAll, $o);
								ar.emulationInput().off('change.tbl');
								ar.next('.bx-checkbox').off('click.tbl');
								f_ar.off('change.tbl');
								f_ar.next('.bx-checkbox').off('click.tbl');
								f._checkbox_check(ar, f_ar);
								f._size_show(ar);
								if(d.more){
									$o_f.find('.more a').prop('href', d.more)
									$o_f.show();
								}
							}
						});
						e.preventDefault();
					})
				},
				_status_few:function(ar, f_ar){
					f_ar.next('.bx-checkbox').removeClass('few');
					if(ar.filter(':not(:checked)').length!==0 && ar.filter(':not(:checked)').length!==ar.length) f_ar.next('.bx-checkbox').addClass('few');
					if(ar.filter(':checked').length) $o_s.text('('+ar.filter(':checked').length+')');
					else $o_s.text('');
				},
				_submit_block:function(ar){
					if(ar.filter(':checked').length==0){$o_a.hide(); return false}
					ar.each(function(){
						var $c=$(this);
						if($c.is(':checked')){
							if($c.data('action')==1){
								$o_a.show();
							}else{
								$o_a.hide(); return false
							}
						}
					})
				},
				_tip:function($t){
					$t.each(function(){
						var n, $b=$(this), $ci;
						if($b.prop('title').length){
							n=$b.prop('title'); $b.prop('title','');
						}else{return true}
						$b.hover(function(){
							$('.bl-tip-selected').remove();
							$ci=$('<div class="bl-tip-selected">'+n+'<span class="arrow"></span></div>')
							$('body').append($ci);
							$ci.css({
								top:($b.offset().top+28),
								left:($b.offset().left+($b.outerWidth()-12))
							});
						}, function(){ 
							$('.bl-tip-selected').remove();
						});
					})
				},
				_checkbox_check:function(ar, f_ar){
					f_ar.each(function(){
						var $c=$(this);
						$c.on('change.tbl', function(){
							f._status_few(ar, f_ar);
						}).next('.bx-checkbox').on('click.tbl', function(){
							state=$c.prop('checked');
							ar.prop('checked', state).change();
							f_ar.prop('checked', state).change();
							f._status_few(ar, f_ar);
						})
					}).change();
					ar.each(function(){
						var $c=$(this), $r=$c.parents('tr');
						$c.on('change.tbl', function(){
							if($c.is(':checked')){
								$r.addClass('selected');
							}else{
								$r.removeClass('selected');
							}
							f._submit_block(ar);
						}).next('.bx-checkbox').on('click.tbl', function(){
							f._status_few(ar, f_ar);
							if(ar.filter(":checked").length==ar.length) state=1;
							else state=0;
							f_ar.prop('checked', state).change();
						})
					}).change();
				}
			});
			// reload
			if($(c.checkboxAll+':first', $o).is(':checked')){
				$(c.checkboxAll, $o).prop('checked', 1).change();
			}
			// tooltip
			f._tip($('.bl-ls-selected dd a', $o));
			// dropdown
			$('.bl-ls-submit', $o).otherMenu();
			f._size_show($('input[type="checkbox"]', $t));
			f._checkbox_check($('input[type="checkbox"]', $t), $(c.checkboxAll, $o));
			f._ajax_tbl();
			//
			$m_bl.append('<a href="#" class="close" title="Sluiten">Sluiten</a>');
			$('.close', $m_bl).on('click',function(e){
				$m_bl.fadeTo(200, 0, function(){$m_bl.remove()});
				e.preventDefault();
			})
		});
	};
	//
	$.fn.scrollTable = function(){
		return this.each(function(){
			var $o=$(this).children('table'), $o_w=$(this).width(), $f, $f_w=$('tr td:first, tr th:first', $o).innerWidth();
			$('tr', $o).each(function(){
				$(this).children('td, th').slice(0,2).height($(this).children('td:first, th:first').height());
			});
			$f=$o.clone();
			$('tr', $f).each(function(){
				$(this).children('td:not(:first), th:not(:first)').remove()
			});
			$('tr', $o).each(function(){
				$(this).children('td:first, th:first').remove()
			});
			$o.before($f);
			$o.wrap($('<div class="el-scroll"></div>').css({'width':$o_w-$f_w}));
			$f.wrap($('<div class="el-fix"></div>').css({'width':$f_w}));
		})
	};
	//
	$.fn.printEdit = function(){
		return this.each(function(){
			var $o=$(this), $dt_rt=$('.pg-fm-rth .bl-fm-info', $o),
					$p_btn=$('.bl-ds-toolbox .print a, .bl-ls-toolbox .print a', $o),
					$u_bl=$('.el-upload input[type="file"]')
					$ac_bl=$('.bl-fm-accord'),
					$m_bl=$('.pg-fm-wrap .bl-fm-ok');
			if($dt_rt.length==1){
				var $dt_rtc=$dt_rt.clone();
				$('.bl-fm-ttl').after($dt_rtc.addClass('bl-fm-info-print'))
			}
			$p_btn.on('click',function(e){
				window.print();
				e.preventDefault();
			})
			
		})
	};
	//
	$.fn.actionForm = function(params){
		var conf = $.extend({
			//locationSchool:'json/location.html?school='
		}, params);
		return this.each(function(){
			var $o=$(this), f=this, c=conf;
			$.extend(f,{
				_inner_show:function($ci, $cb){
					if($ci.is(':checked')) $cb.show();
					else $cb.hide();
				},
				_accord_show:function($ci, $cb){
					if($ci.hasClass('open')){$cb.slideUp(); $ci.removeClass('open')}
					else{$cb.slideDown(); $ci.addClass('open')}
				},
				_size_show:function($ss, $lb){
					if($ss.val()!=0 && $lb.data('url')){
						$.ajax({
							url:$lb.data('url')+'?size='+$ss.val(),
							dataType:'json',
							beforeSend:function(){
								$lb.empty()
							},
							error:function(){},
							success:function(d){
								$lb.html(d.text);
								$('.js-size, .js-copy', $o).fadeIn();
							}
						});
					}else{
						$('.js-size, .js-copy', $o).hide();
					}
				},
				_location_show:function($ss, $lb, $ls){
					if($ss.val()!=0 && $ls.data('url')){
						$.ajax({
							url:$ls.data('url')+'?school='+$ss.val(),
							dataType:'json',
							beforeSend:function(){
								$ls.empty()
							},
							error:function(){},
							success:function(d){
								$.each(d, function(k, v){
									$.each(v, function(){
										$ls.append('<option value="'+this.value+'">'+this.text+'</option>');
									});
								})
								$ls.trigger('refresh')
								$lb.show();
							}
						});
					}else{
						$lb.hide();
					}
				}
			});
			var $ad_bl=$('.elem-data', $o),
					$s_sl=$('.js-school select', $o),
					$u_bl=$('.el-upload input[type="file"]', $o)
					$ac_bl=$('.bl-fm-accord', $o),
					$m_bl=$('.pg-fm-wrap .bl-fm-ok'),
					$s_tbl=$('.un-fm-calc table');
			$s_tbl.each(function(){
				var $i_tlb=$(this), $h=$('thead',$i_tlb), $b=$('tbody',$i_tlb), w_tlb=$i_tlb.width(), h_tlb;
				if($h.length && $b.length){
					$('th', $h).each(function(i){
						$(this).width($(this).width());
						$('tr:first td', $b).eq(i).width($(this).width());
					});
					if($b.height()>=126){h_tlb=126}else{h_tlb='auto'}
					$i_tlb.before($('<table>').width(w_tlb).append($h));
					$i_tlb.css({'position':'relative'}).wrap($('<div></div>').css({'width':w_tlb,'height':h_tlb,'overflow':'auto'}));
					$('td', $b).bind('click', function(){
						$('tr', $b).removeClass('selected')
						$(this).parent().addClass('selected');
						// need push info
					})
				}
			})
			$ad_bl.each(function(){
				var $d_bl=$(this), $d_ch=$d_bl.parents('.elem').children('input[type="checkbox"], input[type="radio"]');
				if($d_ch.length){
					f._inner_show($d_ch, $d_bl);
					$d_ch.on('change', function(){
						$d_ch.closest('form').find('input[name="'+$d_ch.prop('name')+'"]').parent('.elem').find('.elem-data').hide();
						f._inner_show($d_ch, $d_bl);
					})
				}
			});
			if($s_sl.length){
				var $l_bl=$('.js-location', $o), $l_sl=$('select', $l_bl), $l_sz=$('.js-size .size', $o);
				if($l_sl.length){
					f._location_show($s_sl, $l_bl, $l_sl);
					$s_sl.on('change', function(){
						f._location_show($s_sl, $l_bl, $l_sl);
					})
				}else if($l_sz.length){
					f._size_show($s_sl, $l_sz);
					$s_sl.on('change', function(){
						f._size_show($s_sl, $l_sz);
					})
					var $n_dt=$('.el-copy .new a', $o), $e_dt=$('.el-copy .existing a', $o), l_ct=$('.js-contact', $o);
					l_ct.hide();
					$n_dt.on('click', function(){
						$('.js-copy', $o).hide();
						l_ct.find('#f_contactpersoon, #f_telefoonummer').val('');
						l_ct.fadeIn();
						return false
					});
					$e_dt.on('click', function(){
						$.ajax({
							url:$(this).prop('href'),
							dataType:'json',
							beforeSend:function(){
								$('.js-copy', $o).hide();
							},
							success:function(d){
								l_ct.find('#f_contactpersoon').val(d.name);
								l_ct.find('#f_telefoonummer').val(d.tel);
								l_ct.fadeIn();
							}
						});
						return false
					});
				}
			};
			$ac_bl.each(function(){
				var $a_bl=$(this), $a_h=$a_bl.children('dt'), $a_b=$a_bl.children('dd');
				if($a_h.length==1 && $a_b.length==1){
					$a_h.on('click',function(){
						f._accord_show($a_h, $a_b);
					});
					if($a_h.hasClass('open')) $a_b.show();
					else $a_b.hide();
				}
			});
			$m_bl.append('<a href="#" class="close" title="Sluiten">Sluiten</a>');
			$('.close', $m_bl).on('click',function(e){
				$m_bl.fadeTo(200, 0, function(){$m_bl.remove()});
				e.preventDefault();
			})
			/*$u_bl.each(function(){
        $(this).fileupload({
        dataType: 'json',
        add: function (e, data) {
            data.context = $('<button/>').text('Upload')
                .appendTo(document.body)
                .click(function () {
                    data.context = $('<p/>').text('Uploading...').replaceAll($(this));
                    data.submit();
                });
        },
        done: function (e, data) {
            data.context.text('Upload finished.');
        }
    });
      });*/
		})
	};
	//
})(jQuery);

/*
 * jQuery UI Widget 1.10.3+amd
 * https://github.com/blueimp/jQuery-File-Upload
 *
 * Copyright 2013 jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * http://api.jqueryui.com/jQuery.widget/
 */

(function (factory) {
    if (typeof define === "function" && define.amd) {
        // Register as an anonymous AMD module:
        define(["jquery"], factory);
    } else {
        // Browser globals:
        factory(jQuery);
    }
}(function( $, undefined ) {

var uuid = 0,
	slice = Array.prototype.slice,
	_cleanData = $.cleanData;
$.cleanData = function( elems ) {
	for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
		try {
			$( elem ).triggerHandler( "remove" );
		// http://bugs.jquery.com/ticket/8235
		} catch( e ) {}
	}
	_cleanData( elems );
};

$.widget = function( name, base, prototype ) {
	var fullName, existingConstructor, constructor, basePrototype,
		// proxiedPrototype allows the provided prototype to remain unmodified
		// so that it can be used as a mixin for multiple widgets (#8876)
		proxiedPrototype = {},
		namespace = name.split( "." )[ 0 ];

	name = name.split( "." )[ 1 ];
	fullName = namespace + "-" + name;

	if ( !prototype ) {
		prototype = base;
		base = $.Widget;
	}

	// create selector for plugin
	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
		return !!$.data( elem, fullName );
	};

	$[ namespace ] = $[ namespace ] || {};
	existingConstructor = $[ namespace ][ name ];
	constructor = $[ namespace ][ name ] = function( options, element ) {
		// allow instantiation without "new" keyword
		if ( !this._createWidget ) {
			return new constructor( options, element );
		}

		// allow instantiation without initializing for simple inheritance
		// must use "new" keyword (the code above always passes args)
		if ( arguments.length ) {
			this._createWidget( options, element );
		}
	};
	// extend with the existing constructor to carry over any static properties
	$.extend( constructor, existingConstructor, {
		version: prototype.version,
		// copy the object used to create the prototype in case we need to
		// redefine the widget later
		_proto: $.extend( {}, prototype ),
		// track widgets that inherit from this widget in case this widget is
		// redefined after a widget inherits from it
		_childConstructors: []
	});

	basePrototype = new base();
	// we need to make the options hash a property directly on the new instance
	// otherwise we'll modify the options hash on the prototype that we're
	// inheriting from
	basePrototype.options = $.widget.extend( {}, basePrototype.options );
	$.each( prototype, function( prop, value ) {
		if ( !$.isFunction( value ) ) {
			proxiedPrototype[ prop ] = value;
			return;
		}
		proxiedPrototype[ prop ] = (function() {
			var _super = function() {
					return base.prototype[ prop ].apply( this, arguments );
				},
				_superApply = function( args ) {
					return base.prototype[ prop ].apply( this, args );
				};
			return function() {
				var __super = this._super,
					__superApply = this._superApply,
					returnValue;

				this._super = _super;
				this._superApply = _superApply;

				returnValue = value.apply( this, arguments );

				this._super = __super;
				this._superApply = __superApply;

				return returnValue;
			};
		})();
	});
	constructor.prototype = $.widget.extend( basePrototype, {
		// TODO: remove support for widgetEventPrefix
		// always use the name + a colon as the prefix, e.g., draggable:start
		// don't prefix for widgets that aren't DOM-based
		widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
	}, proxiedPrototype, {
		constructor: constructor,
		namespace: namespace,
		widgetName: name,
		widgetFullName: fullName
	});

	// If this widget is being redefined then we need to find all widgets that
	// are inheriting from it and redefine all of them so that they inherit from
	// the new version of this widget. We're essentially trying to replace one
	// level in the prototype chain.
	if ( existingConstructor ) {
		$.each( existingConstructor._childConstructors, function( i, child ) {
			var childPrototype = child.prototype;

			// redefine the child widget using the same prototype that was
			// originally used, but inherit from the new version of the base
			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
		});
		// remove the list of existing child constructors from the old constructor
		// so the old child constructors can be garbage collected
		delete existingConstructor._childConstructors;
	} else {
		base._childConstructors.push( constructor );
	}

	$.widget.bridge( name, constructor );
};

$.widget.extend = function( target ) {
	var input = slice.call( arguments, 1 ),
		inputIndex = 0,
		inputLength = input.length,
		key,
		value;
	for ( ; inputIndex < inputLength; inputIndex++ ) {
		for ( key in input[ inputIndex ] ) {
			value = input[ inputIndex ][ key ];
			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
				// Clone objects
				if ( $.isPlainObject( value ) ) {
					target[ key ] = $.isPlainObject( target[ key ] ) ?
						$.widget.extend( {}, target[ key ], value ) :
						// Don't extend strings, arrays, etc. with objects
						$.widget.extend( {}, value );
				// Copy everything else by reference
				} else {
					target[ key ] = value;
				}
			}
		}
	}
	return target;
};

$.widget.bridge = function( name, object ) {
	var fullName = object.prototype.widgetFullName || name;
	$.fn[ name ] = function( options ) {
		var isMethodCall = typeof options === "string",
			args = slice.call( arguments, 1 ),
			returnValue = this;

		// allow multiple hashes to be passed on init
		options = !isMethodCall && args.length ?
			$.widget.extend.apply( null, [ options ].concat(args) ) :
			options;

		if ( isMethodCall ) {
			this.each(function() {
				var methodValue,
					instance = $.data( this, fullName );
				if ( !instance ) {
					return $.error( "cannot call methods on " + name + " prior to initialization; " +
						"attempted to call method '" + options + "'" );
				}
				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
				}
				methodValue = instance[ options ].apply( instance, args );
				if ( methodValue !== instance && methodValue !== undefined ) {
					returnValue = methodValue && methodValue.jquery ?
						returnValue.pushStack( methodValue.get() ) :
						methodValue;
					return false;
				}
			});
		} else {
			this.each(function() {
				var instance = $.data( this, fullName );
				if ( instance ) {
					instance.option( options || {} )._init();
				} else {
					$.data( this, fullName, new object( options, this ) );
				}
			});
		}

		return returnValue;
	};
};

$.Widget = function( /* options, element */ ) {};
$.Widget._childConstructors = [];

$.Widget.prototype = {
	widgetName: "widget",
	widgetEventPrefix: "",
	defaultElement: "<div>",
	options: {
		disabled: false,

		// callbacks
		create: null
	},
	_createWidget: function( options, element ) {
		element = $( element || this.defaultElement || this )[ 0 ];
		this.element = $( element );
		this.uuid = uuid++;
		this.eventNamespace = "." + this.widgetName + this.uuid;
		this.options = $.widget.extend( {},
			this.options,
			this._getCreateOptions(),
			options );

		this.bindings = $();
		this.hoverable = $();
		this.focusable = $();

		if ( element !== this ) {
			$.data( element, this.widgetFullName, this );
			this._on( true, this.element, {
				remove: function( event ) {
					if ( event.target === element ) {
						this.destroy();
					}
				}
			});
			this.document = $( element.style ?
				// element within the document
				element.ownerDocument :
				// element is window or document
				element.document || element );
			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
		}

		this._create();
		this._trigger( "create", null, this._getCreateEventData() );
		this._init();
	},
	_getCreateOptions: $.noop,
	_getCreateEventData: $.noop,
	_create: $.noop,
	_init: $.noop,

	destroy: function() {
		this._destroy();
		// we can probably remove the unbind calls in 2.0
		// all event bindings should go through this._on()
		this.element
			.unbind( this.eventNamespace )
			// 1.9 BC for #7810
			// TODO remove dual storage
			.removeData( this.widgetName )
			.removeData( this.widgetFullName )
			// support: jquery <1.6.3
			// http://bugs.jquery.com/ticket/9413
			.removeData( $.camelCase( this.widgetFullName ) );
		this.widget()
			.unbind( this.eventNamespace )
			.removeAttr( "aria-disabled" )
			.removeClass(
				this.widgetFullName + "-disabled " +
				"ui-state-disabled" );

		// clean up events and states
		this.bindings.unbind( this.eventNamespace );
		this.hoverable.removeClass( "ui-state-hover" );
		this.focusable.removeClass( "ui-state-focus" );
	},
	_destroy: $.noop,

	widget: function() {
		return this.element;
	},

	option: function( key, value ) {
		var options = key,
			parts,
			curOption,
			i;

		if ( arguments.length === 0 ) {
			// don't return a reference to the internal hash
			return $.widget.extend( {}, this.options );
		}

		if ( typeof key === "string" ) {
			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
			options = {};
			parts = key.split( "." );
			key = parts.shift();
			if ( parts.length ) {
				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
				for ( i = 0; i < parts.length - 1; i++ ) {
					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
					curOption = curOption[ parts[ i ] ];
				}
				key = parts.pop();
				if ( value === undefined ) {
					return curOption[ key ] === undefined ? null : curOption[ key ];
				}
				curOption[ key ] = value;
			} else {
				if ( value === undefined ) {
					return this.options[ key ] === undefined ? null : this.options[ key ];
				}
				options[ key ] = value;
			}
		}

		this._setOptions( options );

		return this;
	},
	_setOptions: function( options ) {
		var key;

		for ( key in options ) {
			this._setOption( key, options[ key ] );
		}

		return this;
	},
	_setOption: function( key, value ) {
		this.options[ key ] = value;

		if ( key === "disabled" ) {
			this.widget()
				.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
				.attr( "aria-disabled", value );
			this.hoverable.removeClass( "ui-state-hover" );
			this.focusable.removeClass( "ui-state-focus" );
		}

		return this;
	},

	enable: function() {
		return this._setOption( "disabled", false );
	},
	disable: function() {
		return this._setOption( "disabled", true );
	},

	_on: function( suppressDisabledCheck, element, handlers ) {
		var delegateElement,
			instance = this;

		// no suppressDisabledCheck flag, shuffle arguments
		if ( typeof suppressDisabledCheck !== "boolean" ) {
			handlers = element;
			element = suppressDisabledCheck;
			suppressDisabledCheck = false;
		}

		// no element argument, shuffle and use this.element
		if ( !handlers ) {
			handlers = element;
			element = this.element;
			delegateElement = this.widget();
		} else {
			// accept selectors, DOM elements
			element = delegateElement = $( element );
			this.bindings = this.bindings.add( element );
		}

		$.each( handlers, function( event, handler ) {
			function handlerProxy() {
				// allow widgets to customize the disabled handling
				// - disabled as an array instead of boolean
				// - disabled class as method for disabling individual parts
				if ( !suppressDisabledCheck &&
						( instance.options.disabled === true ||
							$( this ).hasClass( "ui-state-disabled" ) ) ) {
					return;
				}
				return ( typeof handler === "string" ? instance[ handler ] : handler )
					.apply( instance, arguments );
			}

			// copy the guid so direct unbinding works
			if ( typeof handler !== "string" ) {
				handlerProxy.guid = handler.guid =
					handler.guid || handlerProxy.guid || $.guid++;
			}

			var match = event.match( /^(\w+)\s*(.*)$/ ),
				eventName = match[1] + instance.eventNamespace,
				selector = match[2];
			if ( selector ) {
				delegateElement.delegate( selector, eventName, handlerProxy );
			} else {
				element.bind( eventName, handlerProxy );
			}
		});
	},

	_off: function( element, eventName ) {
		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
		element.unbind( eventName ).undelegate( eventName );
	},

	_delay: function( handler, delay ) {
		function handlerProxy() {
			return ( typeof handler === "string" ? instance[ handler ] : handler )
				.apply( instance, arguments );
		}
		var instance = this;
		return setTimeout( handlerProxy, delay || 0 );
	},

	_hoverable: function( element ) {
		this.hoverable = this.hoverable.add( element );
		this._on( element, {
			mouseenter: function( event ) {
				$( event.currentTarget ).addClass( "ui-state-hover" );
			},
			mouseleave: function( event ) {
				$( event.currentTarget ).removeClass( "ui-state-hover" );
			}
		});
	},

	_focusable: function( element ) {
		this.focusable = this.focusable.add( element );
		this._on( element, {
			focusin: function( event ) {
				$( event.currentTarget ).addClass( "ui-state-focus" );
			},
			focusout: function( event ) {
				$( event.currentTarget ).removeClass( "ui-state-focus" );
			}
		});
	},

	_trigger: function( type, event, data ) {
		var prop, orig,
			callback = this.options[ type ];

		data = data || {};
		event = $.Event( event );
		event.type = ( type === this.widgetEventPrefix ?
			type :
			this.widgetEventPrefix + type ).toLowerCase();
		// the original event may come from any element
		// so we need to reset the target on the new event
		event.target = this.element[ 0 ];

		// copy original event properties over to the new event
		orig = event.originalEvent;
		if ( orig ) {
			for ( prop in orig ) {
				if ( !( prop in event ) ) {
					event[ prop ] = orig[ prop ];
				}
			}
		}

		this.element.trigger( event, data );
		return !( $.isFunction( callback ) &&
			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
			event.isDefaultPrevented() );
	}
};

$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
		if ( typeof options === "string" ) {
			options = { effect: options };
		}
		var hasOptions,
			effectName = !options ?
				method :
				options === true || typeof options === "number" ?
					defaultEffect :
					options.effect || defaultEffect;
		options = options || {};
		if ( typeof options === "number" ) {
			options = { duration: options };
		}
		hasOptions = !$.isEmptyObject( options );
		options.complete = callback;
		if ( options.delay ) {
			element.delay( options.delay );
		}
		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
			element[ method ]( options );
		} else if ( effectName !== method && element[ effectName ] ) {
			element[ effectName ]( options.duration, options.easing, callback );
		} else {
			element.queue(function( next ) {
				$( this )[ method ]();
				if ( callback ) {
					callback.call( element[ 0 ] );
				}
				next();
			});
		}
	};
});

}));
/*
 * jQuery Iframe Transport Plugin 1.7
 * https://github.com/blueimp/jQuery-File-Upload
 *
 * Copyright 2011, Sebastian Tschan
 * https://blueimp.net
 *
 * Licensed under the MIT license:
 * http://www.opensource.org/licenses/MIT
 */

/*jslint unparam: true, nomen: true */
/*global define, window, document */

(function (factory) {
    'use strict';
    if (typeof define === 'function' && define.amd) {
        // Register as an anonymous AMD module:
        define(['jquery'], factory);
    } else {
        // Browser globals:
        factory(window.jQuery);
    }
}(function ($) {
    'use strict';

    // Helper variable to create unique names for the transport iframes:
    var counter = 0;

    // The iframe transport accepts three additional options:
    // options.fileInput: a jQuery collection of file input fields
    // options.paramName: the parameter name for the file form data,
    //  overrides the name property of the file input field(s),
    //  can be a string or an array of strings.
    // options.formData: an array of objects with name and value properties,
    //  equivalent to the return data of .serializeArray(), e.g.:
    //  [{name: 'a', value: 1}, {name: 'b', value: 2}]
    $.ajaxTransport('iframe', function (options) {
        if (options.async) {
            var form,
                iframe,
                addParamChar;
            return {
                send: function (_, completeCallback) {
                    form = $('<form style="display:none;"></form>');
                    form.attr('accept-charset', options.formAcceptCharset);
                    addParamChar = /\?/.test(options.url) ? '&' : '?';
                    // XDomainRequest only supports GET and POST:
                    if (options.type === 'DELETE') {
                        options.url = options.url + addParamChar + '_method=DELETE';
                        options.type = 'POST';
                    } else if (options.type === 'PUT') {
                        options.url = options.url + addParamChar + '_method=PUT';
                        options.type = 'POST';
                    } else if (options.type === 'PATCH') {
                        options.url = options.url + addParamChar + '_method=PATCH';
                        options.type = 'POST';
                    }
                    // javascript:false as initial iframe src
                    // prevents warning popups on HTTPS in IE6.
                    // IE versions below IE8 cannot set the name property of
                    // elements that have already been added to the DOM,
                    // so we set the name along with the iframe HTML markup:
                    counter += 1;
                    iframe = $(
                        '<iframe src="javascript:false;" name="iframe-transport-' +
                            counter + '"></iframe>'
                    ).bind('load', function () {
                        var fileInputClones,
                            paramNames = $.isArray(options.paramName) ?
                                    options.paramName : [options.paramName];
                        iframe
                            .unbind('load')
                            .bind('load', function () {
                                var response;
                                // Wrap in a try/catch block to catch exceptions thrown
                                // when trying to access cross-domain iframe contents:
                                try {
                                    response = iframe.contents();
                                    // Google Chrome and Firefox do not throw an
                                    // exception when calling iframe.contents() on
                                    // cross-domain requests, so we unify the response:
                                    if (!response.length || !response[0].firstChild) {
                                        throw new Error();
                                    }
                                } catch (e) {
                                    response = undefined;
                                }
                                // The complete callback returns the
                                // iframe content document as response object:
                                completeCallback(
                                    200,
                                    'success',
                                    {'iframe': response}
                                );
                                // Fix for IE endless progress bar activity bug
                                // (happens on form submits to iframe targets):
                                $('<iframe src="javascript:false;"></iframe>')
                                    .appendTo(form);
                                window.setTimeout(function () {
                                    // Removing the form in a setTimeout call
                                    // allows Chrome's developer tools to display
                                    // the response result
                                    form.remove();
                                }, 0);
                            });
                        form
                            .prop('target', iframe.prop('name'))
                            .prop('action', options.url)
                            .prop('method', options.type);
                        if (options.formData) {
                            $.each(options.formData, function (index, field) {
                                $('<input type="hidden"/>')
                                    .prop('name', field.name)
                                    .val(field.value)
                                    .appendTo(form);
                            });
                        }
                        if (options.fileInput && options.fileInput.length &&
                                options.type === 'POST') {
                            fileInputClones = options.fileInput.clone();
                            // Insert a clone for each file input field:
                            options.fileInput.after(function (index) {
                                return fileInputClones[index];
                            });
                            if (options.paramName) {
                                options.fileInput.each(function (index) {
                                    $(this).prop(
                                        'name',
                                        paramNames[index] || options.paramName
                                    );
                                });
                            }
                            // Appending the file input fields to the hidden form
                            // removes them from their original location:
                            form
                                .append(options.fileInput)
                                .prop('enctype', 'multipart/form-data')
                                // enctype must be set as encoding for IE:
                                .prop('encoding', 'multipart/form-data');
                        }
                        form.submit();
                        // Insert the file input fields at their original location
                        // by replacing the clones with the originals:
                        if (fileInputClones && fileInputClones.length) {
                            options.fileInput.each(function (index, input) {
                                var clone = $(fileInputClones[index]);
                                $(input).prop('name', clone.prop('name'));
                                clone.replaceWith(input);
                            });
                        }
                    });
                    form.append(iframe).appendTo(document.body);
                },
                abort: function () {
                    if (iframe) {
                        // javascript:false as iframe src aborts the request
                        // and prevents warning popups on HTTPS in IE6.
                        // concat is used to avoid the "Script URL" JSLint error:
                        iframe
                            .unbind('load')
                            .prop('src', 'javascript'.concat(':false;'));
                    }
                    if (form) {
                        form.remove();
                    }
                }
            };
        }
    });

    // The iframe transport returns the iframe content document as response.
    // The following adds converters from iframe to text, json, html, xml
    // and script.
    // Please note that the Content-Type for JSON responses has to be text/plain
    // or text/html, if the browser doesn't include application/json in the
    // Accept header, else IE will show a download dialog.
    // The Content-Type for XML responses on the other hand has to be always
    // application/xml or text/xml, so IE properly parses the XML response.
    // See also
    // https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation
    $.ajaxSetup({
        converters: {
            'iframe text': function (iframe) {
                return iframe && $(iframe[0].body).text();
            },
            'iframe json': function (iframe) {
                return iframe && $.parseJSON($(iframe[0].body).text());
            },
            'iframe html': function (iframe) {
                return iframe && $(iframe[0].body).html();
            },
            'iframe xml': function (iframe) {
                var xmlDoc = iframe && iframe[0];
                return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc :
                        $.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) ||
                            $(xmlDoc.body).html());
            },
            'iframe script': function (iframe) {
                return iframe && $.globalEval($(iframe[0].body).text());
            }
        }
    });

}));

/*
 * jQuery File Upload Plugin 5.32.2
 * https://github.com/blueimp/jQuery-File-Upload
 *
 * Copyright 2010, Sebastian Tschan
 * https://blueimp.net
 *
 * Licensed under the MIT license:
 * http://www.opensource.org/licenses/MIT
 */

/*jslint nomen: true, unparam: true, regexp: true */
/*global define, window, document, location, File, Blob, FormData */

(function (factory) {
    'use strict';
    if (typeof define === 'function' && define.amd) {
        // Register as an anonymous AMD module:
        define([
            'jquery',
            'jquery.ui.widget'
        ], factory);
    } else {
        // Browser globals:
        factory(window.jQuery);
    }
}(function ($) {
    'use strict';

    // Detect file input support, based on
    // http://viljamis.com/blog/2012/file-upload-support-on-mobile/
    $.support.fileInput = !(new RegExp(
        // Handle devices which give false positives for the feature detection:
        '(Android (1\\.[0156]|2\\.[01]))' +
            '|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)' +
            '|(w(eb)?OSBrowser)|(webOS)' +
            '|(Kindle/(1\\.0|2\\.[05]|3\\.0))'
    ).test(window.navigator.userAgent) ||
        // Feature detection for all other devices:
        $('<input type="file">').prop('disabled'));

    // The FileReader API is not actually used, but works as feature detection,
    // as e.g. Safari supports XHR file uploads via the FormData API,
    // but not non-multipart XHR file uploads:
    $.support.xhrFileUpload = !!(window.XMLHttpRequestUpload && window.FileReader);
    $.support.xhrFormDataFileUpload = !!window.FormData;

    // Detect support for Blob slicing (required for chunked uploads):
    $.support.blobSlice = window.Blob && (Blob.prototype.slice ||
        Blob.prototype.webkitSlice || Blob.prototype.mozSlice);

    // The fileupload widget listens for change events on file input fields defined
    // via fileInput setting and paste or drop events of the given dropZone.
    // In addition to the default jQuery Widget methods, the fileupload widget
    // exposes the "add" and "send" methods, to add or directly send files using
    // the fileupload API.
    // By default, files added via file input selection, paste, drag & drop or
    // "add" method are uploaded immediately, but it is possible to override
    // the "add" callback option to queue file uploads.
    $.widget('blueimp.fileupload', {

        options: {
            // The drop target element(s), by the default the complete document.
            // Set to null to disable drag & drop support:
            dropZone: $(document),
            // The paste target element(s), by the default the complete document.
            // Set to null to disable paste support:
            pasteZone: $(document),
            // The file input field(s), that are listened to for change events.
            // If undefined, it is set to the file input fields inside
            // of the widget element on plugin initialization.
            // Set to null to disable the change listener.
            fileInput: undefined,
            // By default, the file input field is replaced with a clone after
            // each input field change event. This is required for iframe transport
            // queues and allows change events to be fired for the same file
            // selection, but can be disabled by setting the following option to false:
            replaceFileInput: true,
            // The parameter name for the file form data (the request argument name).
            // If undefined or empty, the name property of the file input field is
            // used, or "files[]" if the file input name property is also empty,
            // can be a string or an array of strings:
            paramName: undefined,
            // By default, each file of a selection is uploaded using an individual
            // request for XHR type uploads. Set to false to upload file
            // selections in one request each:
            singleFileUploads: true,
            // To limit the number of files uploaded with one XHR request,
            // set the following option to an integer greater than 0:
            limitMultiFileUploads: undefined,
            // Set the following option to true to issue all file upload requests
            // in a sequential order:
            sequentialUploads: false,
            // To limit the number of concurrent uploads,
            // set the following option to an integer greater than 0:
            limitConcurrentUploads: undefined,
            // Set the following option to true to force iframe transport uploads:
            forceIframeTransport: false,
            // Set the following option to the location of a redirect url on the
            // origin server, for cross-domain iframe transport uploads:
            redirect: undefined,
            // The parameter name for the redirect url, sent as part of the form
            // data and set to 'redirect' if this option is empty:
            redirectParamName: undefined,
            // Set the following option to the location of a postMessage window,
            // to enable postMessage transport uploads:
            postMessage: undefined,
            // By default, XHR file uploads are sent as multipart/form-data.
            // The iframe transport is always using multipart/form-data.
            // Set to false to enable non-multipart XHR uploads:
            multipart: true,
            // To upload large files in smaller chunks, set the following option
            // to a preferred maximum chunk size. If set to 0, null or undefined,
            // or the browser does not support the required Blob API, files will
            // be uploaded as a whole.
            maxChunkSize: undefined,
            // When a non-multipart upload or a chunked multipart upload has been
            // aborted, this option can be used to resume the upload by setting
            // it to the size of the already uploaded bytes. This option is most
            // useful when modifying the options object inside of the "add" or
            // "send" callbacks, as the options are cloned for each file upload.
            uploadedBytes: undefined,
            // By default, failed (abort or error) file uploads are removed from the
            // global progress calculation. Set the following option to false to
            // prevent recalculating the global progress data:
            recalculateProgress: true,
            // Interval in milliseconds to calculate and trigger progress events:
            progressInterval: 100,
            // Interval in milliseconds to calculate progress bitrate:
            bitrateInterval: 500,
            // By default, uploads are started automatically when adding files:
            autoUpload: true,

            // Error and info messages:
            messages: {
                uploadedBytes: 'Uploaded bytes exceed file size'
            },

            // Translation function, gets the message key to be translated
            // and an object with context specific data as arguments:
            i18n: function (message, context) {
                message = this.messages[message] || message.toString();
                if (context) {
                    $.each(context, function (key, value) {
                        message = message.replace('{' + key + '}', value);
                    });
                }
                return message;
            },

            // Additional form data to be sent along with the file uploads can be set
            // using this option, which accepts an array of objects with name and
            // value properties, a function returning such an array, a FormData
            // object (for XHR file uploads), or a simple object.
            // The form of the first fileInput is given as parameter to the function:
            formData: function (form) {
                return form.serializeArray();
            },

            // The add callback is invoked as soon as files are added to the fileupload
            // widget (via file input selection, drag & drop, paste or add API call).
            // If the singleFileUploads option is enabled, this callback will be
            // called once for each file in the selection for XHR file uploads, else
            // once for each file selection.
            //
            // The upload starts when the submit method is invoked on the data parameter.
            // The data object contains a files property holding the added files
            // and allows you to override plugin options as well as define ajax settings.
            //
            // Listeners for this callback can also be bound the following way:
            // .bind('fileuploadadd', func);
            //
            // data.submit() returns a Promise object and allows to attach additional
            // handlers using jQuery's Deferred callbacks:
            // data.submit().done(func).fail(func).always(func);
            add: function (e, data) {
                if (data.autoUpload || (data.autoUpload !== false &&
                        $(this).fileupload('option', 'autoUpload'))) {
                    data.process().done(function () {
                        data.submit();
                    });
                }
            },

            // Other callbacks:

            // Callback for the submit event of each file upload:
            // submit: function (e, data) {}, // .bind('fileuploadsubmit', func);

            // Callback for the start of each file upload request:
            // send: function (e, data) {}, // .bind('fileuploadsend', func);

            // Callback for successful uploads:
            // done: function (e, data) {}, // .bind('fileuploaddone', func);

            // Callback for failed (abort or error) uploads:
            // fail: function (e, data) {}, // .bind('fileuploadfail', func);

            // Callback for completed (success, abort or error) requests:
            // always: function (e, data) {}, // .bind('fileuploadalways', func);

            // Callback for upload progress events:
            // progress: function (e, data) {}, // .bind('fileuploadprogress', func);

            // Callback for global upload progress events:
            // progressall: function (e, data) {}, // .bind('fileuploadprogressall', func);

            // Callback for uploads start, equivalent to the global ajaxStart event:
            // start: function (e) {}, // .bind('fileuploadstart', func);

            // Callback for uploads stop, equivalent to the global ajaxStop event:
            // stop: function (e) {}, // .bind('fileuploadstop', func);

            // Callback for change events of the fileInput(s):
            // change: function (e, data) {}, // .bind('fileuploadchange', func);

            // Callback for paste events to the pasteZone(s):
            // paste: function (e, data) {}, // .bind('fileuploadpaste', func);

            // Callback for drop events of the dropZone(s):
            // drop: function (e, data) {}, // .bind('fileuploaddrop', func);

            // Callback for dragover events of the dropZone(s):
            // dragover: function (e) {}, // .bind('fileuploaddragover', func);

            // Callback for the start of each chunk upload request:
            // chunksend: function (e, data) {}, // .bind('fileuploadchunksend', func);

            // Callback for successful chunk uploads:
            // chunkdone: function (e, data) {}, // .bind('fileuploadchunkdone', func);

            // Callback for failed (abort or error) chunk uploads:
            // chunkfail: function (e, data) {}, // .bind('fileuploadchunkfail', func);

            // Callback for completed (success, abort or error) chunk upload requests:
            // chunkalways: function (e, data) {}, // .bind('fileuploadchunkalways', func);

            // The plugin options are used as settings object for the ajax calls.
            // The following are jQuery ajax settings required for the file uploads:
            processData: false,
            contentType: false,
            cache: false
        },

        // A list of options that require reinitializing event listeners and/or
        // special initialization code:
        _specialOptions: [
            'fileInput',
            'dropZone',
            'pasteZone',
            'multipart',
            'forceIframeTransport'
        ],

        _blobSlice: $.support.blobSlice && function () {
            var slice = this.slice || this.webkitSlice || this.mozSlice;
            return slice.apply(this, arguments);
        },

        _BitrateTimer: function () {
            this.timestamp = ((Date.now) ? Date.now() : (new Date()).getTime());
            this.loaded = 0;
            this.bitrate = 0;
            this.getBitrate = function (now, loaded, interval) {
                var timeDiff = now - this.timestamp;
                if (!this.bitrate || !interval || timeDiff > interval) {
                    this.bitrate = (loaded - this.loaded) * (1000 / timeDiff) * 8;
                    this.loaded = loaded;
                    this.timestamp = now;
                }
                return this.bitrate;
            };
        },

        _isXHRUpload: function (options) {
            return !options.forceIframeTransport &&
                ((!options.multipart && $.support.xhrFileUpload) ||
                $.support.xhrFormDataFileUpload);
        },

        _getFormData: function (options) {
            var formData;
            if (typeof options.formData === 'function') {
                return options.formData(options.form);
            }
            if ($.isArray(options.formData)) {
                return options.formData;
            }
            if ($.type(options.formData) === 'object') {
                formData = [];
                $.each(options.formData, function (name, value) {
                    formData.push({name: name, value: value});
                });
                return formData;
            }
            return [];
        },

        _getTotal: function (files) {
            var total = 0;
            $.each(files, function (index, file) {
                total += file.size || 1;
            });
            return total;
        },

        _initProgressObject: function (obj) {
            var progress = {
                loaded: 0,
                total: 0,
                bitrate: 0
            };
            if (obj._progress) {
                $.extend(obj._progress, progress);
            } else {
                obj._progress = progress;
            }
        },

        _initResponseObject: function (obj) {
            var prop;
            if (obj._response) {
                for (prop in obj._response) {
                    if (obj._response.hasOwnProperty(prop)) {
                        delete obj._response[prop];
                    }
                }
            } else {
                obj._response = {};
            }
        },

        _onProgress: function (e, data) {
            if (e.lengthComputable) {
                var now = ((Date.now) ? Date.now() : (new Date()).getTime()),
                    loaded;
                if (data._time && data.progressInterval &&
                        (now - data._time < data.progressInterval) &&
                        e.loaded !== e.total) {
                    return;
                }
                data._time = now;
                loaded = Math.floor(
                    e.loaded / e.total * (data.chunkSize || data._progress.total)
                ) + (data.uploadedBytes || 0);
                // Add the difference from the previously loaded state
                // to the global loaded counter:
                this._progress.loaded += (loaded - data._progress.loaded);
                this._progress.bitrate = this._bitrateTimer.getBitrate(
                    now,
                    this._progress.loaded,
                    data.bitrateInterval
                );
                data._progress.loaded = data.loaded = loaded;
                data._progress.bitrate = data.bitrate = data._bitrateTimer.getBitrate(
                    now,
                    loaded,
                    data.bitrateInterval
                );
                // Trigger a custom progress event with a total data property set
                // to the file size(s) of the current upload and a loaded data
                // property calculated accordingly:
                this._trigger('progress', e, data);
                // Trigger a global progress event for all current file uploads,
                // including ajax calls queued for sequential file uploads:
                this._trigger('progressall', e, this._progress);
            }
        },

        _initProgressListener: function (options) {
            var that = this,
                xhr = options.xhr ? options.xhr() : $.ajaxSettings.xhr();
            // Accesss to the native XHR object is required to add event listeners
            // for the upload progress event:
            if (xhr.upload) {
                $(xhr.upload).bind('progress', function (e) {
                    var oe = e.originalEvent;
                    // Make sure the progress event properties get copied over:
                    e.lengthComputable = oe.lengthComputable;
                    e.loaded = oe.loaded;
                    e.total = oe.total;
                    that._onProgress(e, options);
                });
                options.xhr = function () {
                    return xhr;
                };
            }
        },

        _isInstanceOf: function (type, obj) {
            // Cross-frame instanceof check
            return Object.prototype.toString.call(obj) === '[object ' + type + ']';
        },

        _initXHRData: function (options) {
            var that = this,
                formData,
                file = options.files[0],
                // Ignore non-multipart setting if not supported:
                multipart = options.multipart || !$.support.xhrFileUpload,
                paramName = options.paramName[0];
            options.headers = options.headers || {};
            if (options.contentRange) {
                options.headers['Content-Range'] = options.contentRange;
            }
            if (!multipart || options.blob || !this._isInstanceOf('File', file)) {
                options.headers['Content-Disposition'] = 'attachment; filename="' +
                    encodeURI(file.name) + '"';
            }
            if (!multipart) {
                options.contentType = file.type;
                options.data = options.blob || file;
            } else if ($.support.xhrFormDataFileUpload) {
                if (options.postMessage) {
                    // window.postMessage does not allow sending FormData
                    // objects, so we just add the File/Blob objects to
                    // the formData array and let the postMessage window
                    // create the FormData object out of this array:
                    formData = this._getFormData(options);
                    if (options.blob) {
                        formData.push({
                            name: paramName,
                            value: options.blob
                        });
                    } else {
                        $.each(options.files, function (index, file) {
                            formData.push({
                                name: options.paramName[index] || paramName,
                                value: file
                            });
                        });
                    }
                } else {
                    if (that._isInstanceOf('FormData', options.formData)) {
                        formData = options.formData;
                    } else {
                        formData = new FormData();
                        $.each(this._getFormData(options), function (index, field) {
                            formData.append(field.name, field.value);
                        });
                    }
                    if (options.blob) {
                        formData.append(paramName, options.blob, file.name);
                    } else {
                        $.each(options.files, function (index, file) {
                            // This check allows the tests to run with
                            // dummy objects:
                            if (that._isInstanceOf('File', file) ||
                                    that._isInstanceOf('Blob', file)) {
                                formData.append(
                                    options.paramName[index] || paramName,
                                    file,
                                    file.name
                                );
                            }
                        });
                    }
                }
                options.data = formData;
            }
            // Blob reference is not needed anymore, free memory:
            options.blob = null;
        },

        _initIframeSettings: function (options) {
            var targetHost = $('<a></a>').prop('href', options.url).prop('host');
            // Setting the dataType to iframe enables the iframe transport:
            options.dataType = 'iframe ' + (options.dataType || '');
            // The iframe transport accepts a serialized array as form data:
            options.formData = this._getFormData(options);
            // Add redirect url to form data on cross-domain uploads:
            if (options.redirect && targetHost && targetHost !== location.host) {
                options.formData.push({
                    name: options.redirectParamName || 'redirect',
                    value: options.redirect
                });
            }
        },

        _initDataSettings: function (options) {
            if (this._isXHRUpload(options)) {
                if (!this._chunkedUpload(options, true)) {
                    if (!options.data) {
                        this._initXHRData(options);
                    }
                    this._initProgressListener(options);
                }
                if (options.postMessage) {
                    // Setting the dataType to postmessage enables the
                    // postMessage transport:
                    options.dataType = 'postmessage ' + (options.dataType || '');
                }
            } else {
                this._initIframeSettings(options);
            }
        },

        _getParamName: function (options) {
            var fileInput = $(options.fileInput),
                paramName = options.paramName;
            if (!paramName) {
                paramName = [];
                fileInput.each(function () {
                    var input = $(this),
                        name = input.prop('name') || 'files[]',
                        i = (input.prop('files') || [1]).length;
                    while (i) {
                        paramName.push(name);
                        i -= 1;
                    }
                });
                if (!paramName.length) {
                    paramName = [fileInput.prop('name') || 'files[]'];
                }
            } else if (!$.isArray(paramName)) {
                paramName = [paramName];
            }
            return paramName;
        },

        _initFormSettings: function (options) {
            // Retrieve missing options from the input field and the
            // associated form, if available:
            if (!options.form || !options.form.length) {
                options.form = $(options.fileInput.prop('form'));
                // If the given file input doesn't have an associated form,
                // use the default widget file input's form:
                if (!options.form.length) {
                    options.form = $(this.options.fileInput.prop('form'));
                }
            }
            options.paramName = this._getParamName(options);
            if (!options.url) {
                options.url = options.form.prop('action') || location.href;
            }
            // The HTTP request method must be "POST" or "PUT":
            options.type = (options.type || options.form.prop('method') || '')
                .toUpperCase();
            if (options.type !== 'POST' && options.type !== 'PUT' &&
                    options.type !== 'PATCH') {
                options.type = 'POST';
            }
            if (!options.formAcceptCharset) {
                options.formAcceptCharset = options.form.attr('accept-charset');
            }
        },

        _getAJAXSettings: function (data) {
            var options = $.extend({}, this.options, data);
            this._initFormSettings(options);
            this._initDataSettings(options);
            return options;
        },

        // jQuery 1.6 doesn't provide .state(),
        // while jQuery 1.8+ removed .isRejected() and .isResolved():
        _getDeferredState: function (deferred) {
            if (deferred.state) {
                return deferred.state();
            }
            if (deferred.isResolved()) {
                return 'resolved';
            }
            if (deferred.isRejected()) {
                return 'rejected';
            }
            return 'pending';
        },

        // Maps jqXHR callbacks to the equivalent
        // methods of the given Promise object:
        _enhancePromise: function (promise) {
            promise.success = promise.done;
            promise.error = promise.fail;
            promise.complete = promise.always;
            return promise;
        },

        // Creates and returns a Promise object enhanced with
        // the jqXHR methods abort, success, error and complete:
        _getXHRPromise: function (resolveOrReject, context, args) {
            var dfd = $.Deferred(),
                promise = dfd.promise();
            context = context || this.options.context || promise;
            if (resolveOrReject === true) {
                dfd.resolveWith(context, args);
            } else if (resolveOrReject === false) {
                dfd.rejectWith(context, args);
            }
            promise.abort = dfd.promise;
            return this._enhancePromise(promise);
        },

        // Adds convenience methods to the data callback argument:
        _addConvenienceMethods: function (e, data) {
            var that = this,
                getPromise = function (data) {
                    return $.Deferred().resolveWith(that, [data]).promise();
                };
            data.process = function (resolveFunc, rejectFunc) {
                if (resolveFunc || rejectFunc) {
                    data._processQueue = this._processQueue =
                        (this._processQueue || getPromise(this))
                            .pipe(resolveFunc, rejectFunc);
                }
                return this._processQueue || getPromise(this);
            };
            data.submit = function () {
                if (this.state() !== 'pending') {
                    data.jqXHR = this.jqXHR =
                        (that._trigger('submit', e, this) !== false) &&
                        that._onSend(e, this);
                }
                return this.jqXHR || that._getXHRPromise();
            };
            data.abort = function () {
                if (this.jqXHR) {
                    return this.jqXHR.abort();
                }
                return that._getXHRPromise();
            };
            data.state = function () {
                if (this.jqXHR) {
                    return that._getDeferredState(this.jqXHR);
                }
                if (this._processQueue) {
                    return that._getDeferredState(this._processQueue);
                }
            };
            data.progress = function () {
                return this._progress;
            };
            data.response = function () {
                return this._response;
            };
        },

        // Parses the Range header from the server response
        // and returns the uploaded bytes:
        _getUploadedBytes: function (jqXHR) {
            var range = jqXHR.getResponseHeader('Range'),
                parts = range && range.split('-'),
                upperBytesPos = parts && parts.length > 1 &&
                    parseInt(parts[1], 10);
            return upperBytesPos && upperBytesPos + 1;
        },

        // Uploads a file in multiple, sequential requests
        // by splitting the file up in multiple blob chunks.
        // If the second parameter is true, only tests if the file
        // should be uploaded in chunks, but does not invoke any
        // upload requests:
        _chunkedUpload: function (options, testOnly) {
            options.uploadedBytes = options.uploadedBytes || 0;
            var that = this,
                file = options.files[0],
                fs = file.size,
                ub = options.uploadedBytes,
                mcs = options.maxChunkSize || fs,
                slice = this._blobSlice,
                dfd = $.Deferred(),
                promise = dfd.promise(),
                jqXHR,
                upload;
            if (!(this._isXHRUpload(options) && slice && (ub || mcs < fs)) ||
                    options.data) {
                return false;
            }
            if (testOnly) {
                return true;
            }
            if (ub >= fs) {
                file.error = options.i18n('uploadedBytes');
                return this._getXHRPromise(
                    false,
                    options.context,
                    [null, 'error', file.error]
                );
            }
            // The chunk upload method:
            upload = function () {
                // Clone the options object for each chunk upload:
                var o = $.extend({}, options),
                    currentLoaded = o._progress.loaded;
                o.blob = slice.call(
                    file,
                    ub,
                    ub + mcs,
                    file.type
                );
                // Store the current chunk size, as the blob itself
                // will be dereferenced after data processing:
                o.chunkSize = o.blob.size;
                // Expose the chunk bytes position range:
                o.contentRange = 'bytes ' + ub + '-' +
                    (ub + o.chunkSize - 1) + '/' + fs;
                // Process the upload data (the blob and potential form data):
                that._initXHRData(o);
                // Add progress listeners for this chunk upload:
                that._initProgressListener(o);
                jqXHR = ((that._trigger('chunksend', null, o) !== false && $.ajax(o)) ||
                        that._getXHRPromise(false, o.context))
                    .done(function (result, textStatus, jqXHR) {
                        ub = that._getUploadedBytes(jqXHR) ||
                            (ub + o.chunkSize);
                        // Create a progress event if no final progress event
                        // with loaded equaling total has been triggered
                        // for this chunk:
                        if (currentLoaded + o.chunkSize - o._progress.loaded) {
                            that._onProgress($.Event('progress', {
                                lengthComputable: true,
                                loaded: ub - o.uploadedBytes,
                                total: ub - o.uploadedBytes
                            }), o);
                        }
                        options.uploadedBytes = o.uploadedBytes = ub;
                        o.result = result;
                        o.textStatus = textStatus;
                        o.jqXHR = jqXHR;
                        that._trigger('chunkdone', null, o);
                        that._trigger('chunkalways', null, o);
                        if (ub < fs) {
                            // File upload not yet complete,
                            // continue with the next chunk:
                            upload();
                        } else {
                            dfd.resolveWith(
                                o.context,
                                [result, textStatus, jqXHR]
                            );
                        }
                    })
                    .fail(function (jqXHR, textStatus, errorThrown) {
                        o.jqXHR = jqXHR;
                        o.textStatus = textStatus;
                        o.errorThrown = errorThrown;
                        that._trigger('chunkfail', null, o);
                        that._trigger('chunkalways', null, o);
                        dfd.rejectWith(
                            o.context,
                            [jqXHR, textStatus, errorThrown]
                        );
                    });
            };
            this._enhancePromise(promise);
            promise.abort = function () {
                return jqXHR.abort();
            };
            upload();
            return promise;
        },

        _beforeSend: function (e, data) {
            if (this._active === 0) {
                // the start callback is triggered when an upload starts
                // and no other uploads are currently running,
                // equivalent to the global ajaxStart event:
                this._trigger('start');
                // Set timer for global bitrate progress calculation:
                this._bitrateTimer = new this._BitrateTimer();
                // Reset the global progress values:
                this._progress.loaded = this._progress.total = 0;
                this._progress.bitrate = 0;
            }
            // Make sure the container objects for the .response() and
            // .progress() methods on the data object are available
            // and reset to their initial state:
            this._initResponseObject(data);
            this._initProgressObject(data);
            data._progress.loaded = data.loaded = data.uploadedBytes || 0;
            data._progress.total = data.total = this._getTotal(data.files) || 1;
            data._progress.bitrate = data.bitrate = 0;
            this._active += 1;
            // Initialize the global progress values:
            this._progress.loaded += data.loaded;
            this._progress.total += data.total;
        },

        _onDone: function (result, textStatus, jqXHR, options) {
            var total = options._progress.total,
                response = options._response;
            if (options._progress.loaded < total) {
                // Create a progress event if no final progress event
                // with loaded equaling total has been triggered:
                this._onProgress($.Event('progress', {
                    lengthComputable: true,
                    loaded: total,
                    total: total
                }), options);
            }
            response.result = options.result = result;
            response.textStatus = options.textStatus = textStatus;
            response.jqXHR = options.jqXHR = jqXHR;
            this._trigger('done', null, options);
        },

        _onFail: function (jqXHR, textStatus, errorThrown, options) {
            var response = options._response;
            if (options.recalculateProgress) {
                // Remove the failed (error or abort) file upload from
                // the global progress calculation:
                this._progress.loaded -= options._progress.loaded;
                this._progress.total -= options._progress.total;
            }
            response.jqXHR = options.jqXHR = jqXHR;
            response.textStatus = options.textStatus = textStatus;
            response.errorThrown = options.errorThrown = errorThrown;
            this._trigger('fail', null, options);
        },

        _onAlways: function (jqXHRorResult, textStatus, jqXHRorError, options) {
            // jqXHRorResult, textStatus and jqXHRorError are added to the
            // options object via done and fail callbacks
            this._trigger('always', null, options);
        },

        _onSend: function (e, data) {
            if (!data.submit) {
                this._addConvenienceMethods(e, data);
            }
            var that = this,
                jqXHR,
                aborted,
                slot,
                pipe,
                options = that._getAJAXSettings(data),
                send = function () {
                    that._sending += 1;
                    // Set timer for bitrate progress calculation:
                    options._bitrateTimer = new that._BitrateTimer();
                    jqXHR = jqXHR || (
                        ((aborted || that._trigger('send', e, options) === false) &&
                        that._getXHRPromise(false, options.context, aborted)) ||
                        that._chunkedUpload(options) || $.ajax(options)
                    ).done(function (result, textStatus, jqXHR) {
                        that._onDone(result, textStatus, jqXHR, options);
                    }).fail(function (jqXHR, textStatus, errorThrown) {
                        that._onFail(jqXHR, textStatus, errorThrown, options);
                    }).always(function (jqXHRorResult, textStatus, jqXHRorError) {
                        that._onAlways(
                            jqXHRorResult,
                            textStatus,
                            jqXHRorError,
                            options
                        );
                        that._sending -= 1;
                        that._active -= 1;
                        if (options.limitConcurrentUploads &&
                                options.limitConcurrentUploads > that._sending) {
                            // Start the next queued upload,
                            // that has not been aborted:
                            var nextSlot = that._slots.shift();
                            while (nextSlot) {
                                if (that._getDeferredState(nextSlot) === 'pending') {
                                    nextSlot.resolve();
                                    break;
                                }
                                nextSlot = that._slots.shift();
                            }
                        }
                        if (that._active === 0) {
                            // The stop callback is triggered when all uploads have
                            // been completed, equivalent to the global ajaxStop event:
                            that._trigger('stop');
                        }
                    });
                    return jqXHR;
                };
            this._beforeSend(e, options);
            if (this.options.sequentialUploads ||
                    (this.options.limitConcurrentUploads &&
                    this.options.limitConcurrentUploads <= this._sending)) {
                if (this.options.limitConcurrentUploads > 1) {
                    slot = $.Deferred();
                    this._slots.push(slot);
                    pipe = slot.pipe(send);
                } else {
                    this._sequence = this._sequence.pipe(send, send);
                    pipe = this._sequence;
                }
                // Return the piped Promise object, enhanced with an abort method,
                // which is delegated to the jqXHR object of the current upload,
                // and jqXHR callbacks mapped to the equivalent Promise methods:
                pipe.abort = function () {
                    aborted = [undefined, 'abort', 'abort'];
                    if (!jqXHR) {
                        if (slot) {
                            slot.rejectWith(options.context, aborted);
                        }
                        return send();
                    }
                    return jqXHR.abort();
                };
                return this._enhancePromise(pipe);
            }
            return send();
        },

        _onAdd: function (e, data) {
            var that = this,
                result = true,
                options = $.extend({}, this.options, data),
                limit = options.limitMultiFileUploads,
                paramName = this._getParamName(options),
                paramNameSet,
                paramNameSlice,
                fileSet,
                i;
            if (!(options.singleFileUploads || limit) ||
                    !this._isXHRUpload(options)) {
                fileSet = [data.files];
                paramNameSet = [paramName];
            } else if (!options.singleFileUploads && limit) {
                fileSet = [];
                paramNameSet = [];
                for (i = 0; i < data.files.length; i += limit) {
                    fileSet.push(data.files.slice(i, i + limit));
                    paramNameSlice = paramName.slice(i, i + limit);
                    if (!paramNameSlice.length) {
                        paramNameSlice = paramName;
                    }
                    paramNameSet.push(paramNameSlice);
                }
            } else {
                paramNameSet = paramName;
            }
            data.originalFiles = data.files;
            $.each(fileSet || data.files, function (index, element) {
                var newData = $.extend({}, data);
                newData.files = fileSet ? element : [element];
                newData.paramName = paramNameSet[index];
                that._initResponseObject(newData);
                that._initProgressObject(newData);
                that._addConvenienceMethods(e, newData);
                result = that._trigger('add', e, newData);
                return result;
            });
            return result;
        },

        _replaceFileInput: function (input) {
            var inputClone = input.clone(true);
            $('<form></form>').append(inputClone)[0].reset();
            // Detaching allows to insert the fileInput on another form
            // without loosing the file input value:
            input.after(inputClone).detach();
            // Avoid memory leaks with the detached file input:
            $.cleanData(input.unbind('remove'));
            // Replace the original file input element in the fileInput
            // elements set with the clone, which has been copied including
            // event handlers:
            this.options.fileInput = this.options.fileInput.map(function (i, el) {
                if (el === input[0]) {
                    return inputClone[0];
                }
                return el;
            });
            // If the widget has been initialized on the file input itself,
            // override this.element with the file input clone:
            if (input[0] === this.element[0]) {
                this.element = inputClone;
            }
        },

        _handleFileTreeEntry: function (entry, path) {
            var that = this,
                dfd = $.Deferred(),
                errorHandler = function (e) {
                    if (e && !e.entry) {
                        e.entry = entry;
                    }
                    // Since $.when returns immediately if one
                    // Deferred is rejected, we use resolve instead.
                    // This allows valid files and invalid items
                    // to be returned together in one set:
                    dfd.resolve([e]);
                },
                dirReader;
            path = path || '';
            if (entry.isFile) {
                if (entry._file) {
                    // Workaround for Chrome bug #149735
                    entry._file.relativePath = path;
                    dfd.resolve(entry._file);
                } else {
                    entry.file(function (file) {
                        file.relativePath = path;
                        dfd.resolve(file);
                    }, errorHandler);
                }
            } else if (entry.isDirectory) {
                dirReader = entry.createReader();
                dirReader.readEntries(function (entries) {
                    that._handleFileTreeEntries(
                        entries,
                        path + entry.name + '/'
                    ).done(function (files) {
                        dfd.resolve(files);
                    }).fail(errorHandler);
                }, errorHandler);
            } else {
                // Return an empy list for file system items
                // other than files or directories:
                dfd.resolve([]);
            }
            return dfd.promise();
        },

        _handleFileTreeEntries: function (entries, path) {
            var that = this;
            return $.when.apply(
                $,
                $.map(entries, function (entry) {
                    return that._handleFileTreeEntry(entry, path);
                })
            ).pipe(function () {
                return Array.prototype.concat.apply(
                    [],
                    arguments
                );
            });
        },

        _getDroppedFiles: function (dataTransfer) {
            dataTransfer = dataTransfer || {};
            var items = dataTransfer.items;
            if (items && items.length && (items[0].webkitGetAsEntry ||
                    items[0].getAsEntry)) {
                return this._handleFileTreeEntries(
                    $.map(items, function (item) {
                        var entry;
                        if (item.webkitGetAsEntry) {
                            entry = item.webkitGetAsEntry();
                            if (entry) {
                                // Workaround for Chrome bug #149735:
                                entry._file = item.getAsFile();
                            }
                            return entry;
                        }
                        return item.getAsEntry();
                    })
                );
            }
            return $.Deferred().resolve(
                $.makeArray(dataTransfer.files)
            ).promise();
        },

        _getSingleFileInputFiles: function (fileInput) {
            fileInput = $(fileInput);
            var entries = fileInput.prop('webkitEntries') ||
                    fileInput.prop('entries'),
                files,
                value;
            if (entries && entries.length) {
                return this._handleFileTreeEntries(entries);
            }
            files = $.makeArray(fileInput.prop('files'));
            if (!files.length) {
                value = fileInput.prop('value');
                if (!value) {
                    return $.Deferred().resolve([]).promise();
                }
                // If the files property is not available, the browser does not
                // support the File API and we add a pseudo File object with
                // the input value as name with path information removed:
                files = [{name: value.replace(/^.*\\/, '')}];
            } else if (files[0].name === undefined && files[0].fileName) {
                // File normalization for Safari 4 and Firefox 3:
                $.each(files, function (index, file) {
                    file.name = file.fileName;
                    file.size = file.fileSize;
                });
            }
            return $.Deferred().resolve(files).promise();
        },

        _getFileInputFiles: function (fileInput) {
            if (!(fileInput instanceof $) || fileInput.length === 1) {
                return this._getSingleFileInputFiles(fileInput);
            }
            return $.when.apply(
                $,
                $.map(fileInput, this._getSingleFileInputFiles)
            ).pipe(function () {
                return Array.prototype.concat.apply(
                    [],
                    arguments
                );
            });
        },

        _onChange: function (e) {
            var that = this,
                data = {
                    fileInput: $(e.target),
                    form: $(e.target.form)
                };
            this._getFileInputFiles(data.fileInput).always(function (files) {
                data.files = files;
                if (that.options.replaceFileInput) {
                    that._replaceFileInput(data.fileInput);
                }
                if (that._trigger('change', e, data) !== false) {
                    that._onAdd(e, data);
                }
            });
        },

        _onPaste: function (e) {
            var items = e.originalEvent && e.originalEvent.clipboardData &&
                    e.originalEvent.clipboardData.items,
                data = {files: []};
            if (items && items.length) {
                $.each(items, function (index, item) {
                    var file = item.getAsFile && item.getAsFile();
                    if (file) {
                        data.files.push(file);
                    }
                });
                if (this._trigger('paste', e, data) === false ||
                        this._onAdd(e, data) === false) {
                    return false;
                }
            }
        },

        _onDrop: function (e) {
            e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
            var that = this,
                dataTransfer = e.dataTransfer,
                data = {};
            if (dataTransfer && dataTransfer.files && dataTransfer.files.length) {
                e.preventDefault();
                this._getDroppedFiles(dataTransfer).always(function (files) {
                    data.files = files;
                    if (that._trigger('drop', e, data) !== false) {
                        that._onAdd(e, data);
                    }
                });
            }
        },

        _onDragOver: function (e) {
            e.dataTransfer = e.originalEvent && e.originalEvent.dataTransfer;
            var dataTransfer = e.dataTransfer;
            if (dataTransfer) {
                if (this._trigger('dragover', e) === false) {
                    return false;
                }
                if ($.inArray('Files', dataTransfer.types) !== -1) {
                    dataTransfer.dropEffect = 'copy';
                    e.preventDefault();
                }
            }
        },

        _initEventHandlers: function () {
            if (this._isXHRUpload(this.options)) {
                this._on(this.options.dropZone, {
                    dragover: this._onDragOver,
                    drop: this._onDrop
                });
                this._on(this.options.pasteZone, {
                    paste: this._onPaste
                });
            }
            if ($.support.fileInput) {
                this._on(this.options.fileInput, {
                    change: this._onChange
                });
            }
        },

        _destroyEventHandlers: function () {
            this._off(this.options.dropZone, 'dragover drop');
            this._off(this.options.pasteZone, 'paste');
            this._off(this.options.fileInput, 'change');
        },

        _setOption: function (key, value) {
            var reinit = $.inArray(key, this._specialOptions) !== -1;
            if (reinit) {
                this._destroyEventHandlers();
            }
            this._super(key, value);
            if (reinit) {
                this._initSpecialOptions();
                this._initEventHandlers();
            }
        },

        _initSpecialOptions: function () {
            var options = this.options;
            if (options.fileInput === undefined) {
                options.fileInput = this.element.is('input[type="file"]') ?
                        this.element : this.element.find('input[type="file"]');
            } else if (!(options.fileInput instanceof $)) {
                options.fileInput = $(options.fileInput);
            }
            if (!(options.dropZone instanceof $)) {
                options.dropZone = $(options.dropZone);
            }
            if (!(options.pasteZone instanceof $)) {
                options.pasteZone = $(options.pasteZone);
            }
        },

        _getRegExp: function (str) {
            var parts = str.split('/'),
                modifiers = parts.pop();
            parts.shift();
            return new RegExp(parts.join('/'), modifiers);
        },

        _isRegExpOption: function (key, value) {
            return key !== 'url' && $.type(value) === 'string' &&
                /^\/.*\/[igm]{0,3}$/.test(value);
        },

        _initDataAttributes: function () {
            var that = this,
                options = this.options;
            // Initialize options set via HTML5 data-attributes:
            $.each(
                $(this.element[0].cloneNode(false)).data(),
                function (key, value) {
                    if (that._isRegExpOption(key, value)) {
                        value = that._getRegExp(value);
                    }
                    options[key] = value;
                }
            );
        },

        _create: function () {
            this._initDataAttributes();
            this._initSpecialOptions();
            this._slots = [];
            this._sequence = this._getXHRPromise(true);
            this._sending = this._active = 0;
            this._initProgressObject(this);
            this._initEventHandlers();
        },

        // This method is exposed to the widget API and allows to query
        // the number of active uploads:
        active: function () {
            return this._active;
        },

        // This method is exposed to the widget API and allows to query
        // the widget upload progress.
        // It returns an object with loaded, total and bitrate properties
        // for the running uploads:
        progress: function () {
            return this._progress;
        },

        // This method is exposed to the widget API and allows adding files
        // using the fileupload API. The data parameter accepts an object which
        // must have a files property and can contain additional options:
        // .fileupload('add', {files: filesList});
        add: function (data) {
            var that = this;
            if (!data || this.options.disabled) {
                return;
            }
            if (data.fileInput && !data.files) {
                this._getFileInputFiles(data.fileInput).always(function (files) {
                    data.files = files;
                    that._onAdd(null, data);
                });
            } else {
                data.files = $.makeArray(data.files);
                this._onAdd(null, data);
            }
        },

        // This method is exposed to the widget API and allows sending files
        // using the fileupload API. The data parameter accepts an object which
        // must have a files or fileInput property and can contain additional options:
        // .fileupload('send', {files: filesList});
        // The method returns a Promise object for the file upload call.
        send: function (data) {
            if (data && !this.options.disabled) {
                if (data.fileInput && !data.files) {
                    var that = this,
                        dfd = $.Deferred(),
                        promise = dfd.promise(),
                        jqXHR,
                        aborted;
                    promise.abort = function () {
                        aborted = true;
                        if (jqXHR) {
                            return jqXHR.abort();
                        }
                        dfd.reject(null, 'abort', 'abort');
                        return promise;
                    };
                    this._getFileInputFiles(data.fileInput).always(
                        function (files) {
                            if (aborted) {
                                return;
                            }
                            if (!files.length) {
                                dfd.reject();
                                return;
                            }
                            data.files = files;
                            jqXHR = that._onSend(null, data).then(
                                function (result, textStatus, jqXHR) {
                                    dfd.resolve(result, textStatus, jqXHR);
                                },
                                function (jqXHR, textStatus, errorThrown) {
                                    dfd.reject(jqXHR, textStatus, errorThrown);
                                }
                            );
                        }
                    );
                    return this._enhancePromise(promise);
                }
                data.files = $.makeArray(data.files);
                if (data.files.length) {
                    return this._onSend(null, data);
                }
            }
            return this._getXHRPromise(false, data && data.context);
        }

    });

}));
!function(e){function t(e){this.ele=e,this.displayedMonth=null,this.displayedYear=null,this.startDate=null,this.endDate=null,this.showYearNavigation=null,this.closeOnSelect=null,this.displayClose=null,this.rememberViewedMonth=null,this.selectMultiple=null,this.numSelectable=null,this.numSelected=null,this.verticalPosition=null,this.horizontalPosition=null,this.verticalOffset=null,this.horizontalOffset=null,this.button=null,this.renderCallback=[],this.selectedDates={},this.inline=null,this.context="#dp-popup",this.settings={}}function s(t){return t._dpId?e.event._dpCache[t._dpId]:!1}e.fn.extend({renderCalendar:function(t){var s=function(e){return document.createElement(e)};if(t=e.extend({},e.fn.datePicker.defaults,t),t.showHeader!=e.dpConst.SHOW_HEADER_NONE)for(var a=e(s("tr")),i=Date.firstDayOfWeek;i<Date.firstDayOfWeek+7;i++){var n=i%7,r=Date.dayNames[n];a.append(jQuery(s("th")).attr({scope:"col",abbr:r,title:r,"class":0==n||6==n?"weekend":"weekday"}).html(t.showHeader==e.dpConst.SHOW_HEADER_SHORT?r.substr(0,1):r))}var d=e(s("table")).addClass("js-calendar").append(t.showHeader!=e.dpConst.SHOW_HEADER_NONE?e(s("thead")).append(a):s("thead")),l=e(s("tbody")),o=(new Date).zeroTime();o.setHours(12);var h=void 0==t.month?o.getMonth():t.month,c=t.year||o.getFullYear(),u=new Date(c,h,1,12,0,0),p=Date.firstDayOfWeek-u.getDay()+1;p>1&&(p-=7);var f=Math.ceil((-1*p+1+u.getDaysInMonth())/7);u.addDays(p-1);for(var m=function(s){return function(){if(t.hoverClass){var a=e(this);t.selectWeek?s&&!a.is(".disabled")&&a.parent().addClass("activeWeekHover"):a.addClass(t.hoverClass)}}},D=function(){if(t.hoverClass){var s=e(this);s.removeClass(t.hoverClass),s.parent().removeClass("activeWeekHover")}},v=0;v++<f;){for(var y=jQuery(s("tr")),g=t.dpController?u>t.dpController.startDate:!1,i=0;7>i;i++){var b=u.getMonth()==h,C=e(s("td")).text(u.getDate()+"").addClass((b?"current-month ":"other-month ")+(u.isWeekend()?"weekend ":"weekday ")+(b&&u.getTime()==o.getTime()?"today ":"")).data("datePickerDate",u.asString()).hover(m(g),D);y.append(C),t.renderCallback&&t.renderCallback(C,u,h,c),u=new Date(u.getFullYear(),u.getMonth(),u.getDate()+1,12,0,0)}l.append(y)}return d.append(l),this.each(function(){e(this).empty().append(d)})},datePicker:function(s){return e.event._dpCache||(e.event._dpCache=[]),s=e.extend({},e.fn.datePicker.defaults,s),this.each(function(){var a=e(this),i=!0;this._dpId||(this._dpId=e.guid++,e.event._dpCache[this._dpId]=new t(this),i=!1),s.inline&&(s.createButton=!1,s.displayClose=!1,s.closeOnSelect=!1,a.empty());var n=e.event._dpCache[this._dpId];if(n.init(s),!i&&s.createButton&&(n.button=e('<a href="#" class="dp-choose-date" title="'+e.dpText.TEXT_CHOOSE_DATE+'">'+e.dpText.TEXT_CHOOSE_DATE+"</a>").bind("click",function(){return a.dpDisplay(this),this.blur(),!1}),a.after(n.button)),!i&&a.is(":text")){a.bind("dateSelected",function(e,t){this.value=t.asString()}).bind("change",function(){if(""==this.value)n.clearSelected();else{var e=Date.fromString(this.value);e&&n.setSelected(e,!0,!0)}}),s.clickInput&&a.bind("click",function(){a.trigger("change"),a.dpDisplay()});var r=Date.fromString(this.value);""!=this.value&&r&&n.setSelected(r,!0,!0)}a.addClass("dp-applied").prop("autocomplete","off")})},dpSetDisabled:function(e){return a.call(this,"setDisabled",e)},dpSetStartDate:function(e){return a.call(this,"setStartDate",e)},dpSetEndDate:function(e){return a.call(this,"setEndDate",e)},dpGetSelected:function(){var e=s(this[0]);return e?e.getSelected():null},dpSetSelected:function(e,t,s,i){return void 0==t&&(t=!0),void 0==s&&(s=!0),void 0==i&&(i=!0),a.call(this,"setSelected",Date.fromString(e),t,s,i)},dpSetDisplayedMonth:function(e,t){return a.call(this,"setDisplayedMonth",Number(e),Number(t),!0)},dpDisplay:function(e){return a.call(this,"display",e)},dpSetRenderCallback:function(e){return a.call(this,"setRenderCallback",e)},dpSetPosition:function(e,t){return a.call(this,"setPosition",e,t)},dpSetOffset:function(e,t){return a.call(this,"setOffset",e,t)},dpClose:function(){return a.call(this,"_closeCalendar",!1,this[0])},dpRerenderCalendar:function(){return a.call(this,"_rerenderCalendar")},_dpDestroy:function(){}});var a=function(e,t,a,i,n){return this.each(function(){var r=s(this);r&&r[e](t,a,i,n)})};e.extend(t.prototype,{init:function(e){this.setStartDate(e.startDate),this.setEndDate(e.endDate),this.setDisplayedMonth(Number(e.month),Number(e.year)),this.setRenderCallback(e.renderCallback),this.showYearNavigation=e.showYearNavigation,this.closeOnSelect=e.closeOnSelect,this.displayClose=e.displayClose,this.rememberViewedMonth=e.rememberViewedMonth,this.selectMultiple=e.selectMultiple,this.numSelectable=e.selectMultiple?e.numSelectable:1,this.numSelected=0,this.verticalPosition=e.verticalPosition,this.horizontalPosition=e.horizontalPosition,this.hoverClass=e.hoverClass,this.setOffset(e.verticalOffset,e.horizontalOffset),this.inline=e.inline,this.settings=e,this.inline&&(this.context=this.ele,this.display())},setStartDate:function(e){e&&(this.startDate=e instanceof Date?e:Date.fromString(e)),this.startDate||(this.startDate=(new Date).zeroTime()),this.setDisplayedMonth(this.displayedMonth,this.displayedYear)},setEndDate:function(e){e&&(this.endDate=e instanceof Date?e:Date.fromString(e)),this.endDate||(this.endDate=new Date("12/31/2999")),this.endDate.getTime()<this.startDate.getTime()&&(this.endDate=this.startDate),this.setDisplayedMonth(this.displayedMonth,this.displayedYear)},setPosition:function(e,t){this.verticalPosition=e,this.horizontalPosition=t},setOffset:function(e,t){this.verticalOffset=parseInt(e)||0,this.horizontalOffset=parseInt(t)||0},setDisabled:function(t){$e=e(this.ele),$e[t?"addClass":"removeClass"]("dp-disabled"),this.button&&($but=e(this.button),$but[t?"addClass":"removeClass"]("dp-disabled"),$but.attr("title",t?"":e.dpText.TEXT_CHOOSE_DATE)),$e.is(":text")&&$e.attr("disabled",t?"disabled":"")},setDisplayedMonth:function(t,s,a){if(void 0!=this.startDate&&void 0!=this.endDate){var i=new Date(this.startDate.getTime());i.setDate(1);var n=new Date(this.endDate.getTime());n.setDate(1);var r;!t&&!s||isNaN(t)&&isNaN(s)?(r=(new Date).zeroTime(),r.setDate(1)):r=isNaN(t)?new Date(s,this.displayedMonth,1):isNaN(s)?new Date(this.displayedYear,t,1):new Date(s,t,1),r.getTime()<i.getTime()?r=i:r.getTime()>n.getTime()&&(r=n);var d=this.displayedMonth,l=this.displayedYear;this.displayedMonth=r.getMonth(),this.displayedYear=r.getFullYear(),!a||this.displayedMonth==d&&this.displayedYear==l||(this._rerenderCalendar(),e(this.ele).trigger("dpMonthChanged",[this.displayedMonth,this.displayedYear]))}},setSelected:function(t,s,a,i){if(!(t<this.startDate||t.zeroTime()>this.endDate.zeroTime())){var n=this.settings;if(!(n.selectWeek&&(t=t.addDays(-(t.getDay()-Date.firstDayOfWeek+7)%7),t<this.startDate))&&s!=this.isSelected(t)){if(0==this.selectMultiple)this.clearSelected();else if(s&&this.numSelected==this.numSelectable)return;!a||this.displayedMonth==t.getMonth()&&this.displayedYear==t.getFullYear()||this.setDisplayedMonth(t.getMonth(),t.getFullYear(),!0),this.selectedDates[t.asString()]=s,this.numSelected+=s?1:-1;var r,d="td."+(t.getMonth()==this.displayedMonth?"current-month":"other-month");if(e(d,this.context).each(function(){e(this).data("datePickerDate")==t.asString()&&(r=e(this),n.selectWeek&&r.parent()[s?"addClass":"removeClass"]("selectedWeek"),r[s?"addClass":"removeClass"]("selected"))}),e("td",this.context).not(".selected")[this.selectMultiple&&this.numSelected==this.numSelectable?"addClass":"removeClass"]("unselectable"),i){var n=this.isSelected(t);$e=e(this.ele);var l=Date.fromString(t.asString());$e.trigger("dateSelected",[l,r,n]),$e.trigger("change")}}}},isSelected:function(e){return this.selectedDates[e.asString()]},getSelected:function(){var e=[];for(var t in this.selectedDates)1==this.selectedDates[t]&&e.push(Date.fromString(t));return e},clearSelected:function(){this.selectedDates={},this.numSelected=0,e("td.selected",this.context).removeClass("selected").parent().removeClass("selectedWeek")},display:function(){if(!e(this.ele).is(".dp-disabled")){var t,s,a,i=this,n=e(this.ele),r=n.offset();if(i.inline)t=e(this.ele),s={id:"calendar-"+this.ele._dpId,"class":"dp-popup dp-popup-inline"},e(".dp-popup",t).remove(),a={};else{t=e("body"),s={id:"dp-popup","class":"dp-popup"},a={top:r.top+n.outerHeight()+i.verticalOffset,left:r.left+i.horizontalOffset};var d=function(t){for(var s=t.target,a=e("#dp-popup")[0];;){if(s==a)return!0;if(s==document)return i._closeCalendar(),!1;s=e(s).parent()[0]}};this._checkMouse=d,i._closeCalendar(!0),e(document).bind("keydown.datepicker",function(e){27==e.keyCode&&i._closeCalendar()})}if(!i.rememberViewedMonth){var l=this.getSelected()[0];l&&(l=new Date(l),this.setDisplayedMonth(l.getMonth(),l.getFullYear(),!1))}t.append(e("<div></div>").attr(s).css(a).append(e("<h2></h2>"),e('<div class="dp-nav-prev"></div>').append(e('<a class="dp-nav-prev-year" href="#" title="'+e.dpText.TEXT_PREV_YEAR+'">&lsaquo;&lsaquo;</a>').bind("click",function(){return i._displayNewMonth.call(i,this,0,-1)}),e('<a class="dp-nav-prev-month" href="#" title="'+e.dpText.TEXT_PREV_MONTH+'">&lsaquo;</a>').bind("click",function(){return i._displayNewMonth.call(i,this,-1,0)})),e('<div class="dp-nav-next"></div>').append(e('<a class="dp-nav-next-year" href="#" title="'+e.dpText.TEXT_NEXT_YEAR+'">&rsaquo;&rsaquo;</a>').bind("click",function(){return i._displayNewMonth.call(i,this,0,1)}),e('<a class="dp-nav-next-month" href="#" title="'+e.dpText.TEXT_NEXT_MONTH+'">&rsaquo;</a>').bind("click",function(){return i._displayNewMonth.call(i,this,1,0)})),e('<div class="dp-calendar"></div>')).bgIframe());var o=this.inline?e(".dp-popup",this.context):e("#dp-popup");0==this.showYearNavigation&&e(".dp-nav-prev-year, .dp-nav-next-year",i.context).css("display","none"),this.displayClose&&o.append(e('<a href="#" id="dp-close">'+e.dpText.TEXT_CLOSE+"</a>").bind("click",function(){return i._closeCalendar(),!1})),i._renderCalendar(),e(this.ele).trigger("dpDisplayed",o),i.inline||(this.verticalPosition==e.dpConst.POS_BOTTOM&&o.css("top",r.top+n.height()-o.height()+i.verticalOffset),this.horizontalPosition==e.dpConst.POS_RIGHT&&o.css("left",r.left+n.width()-o.width()+i.horizontalOffset),this.horizontalPosition==e.dpConst.POS_CUSTOM&&this.verticalPosition==e.dpConst.POS_CUSTOM&&o.css({left:r.left+n.outerWidth()+i.horizontalOffset+5,top:r.top-o.height()/2+n.outerHeight()/2}),e(document).bind("mousedown.datepicker",this._checkMouse))}},setRenderCallback:function(e){null!=e&&(e&&"function"==typeof e&&(e=[e]),this.renderCallback=this.renderCallback.concat(e))},cellRender:function(t,s){var a=this.dpController,i=new Date(s.getTime());t.bind("click",function(){var t=e(this);if(!t.is(".disabled")&&(a.setSelected(i,!t.is(".selected")||!a.selectMultiple,!1,!0),a.closeOnSelect)){if(a.settings.autoFocusNextInput){var s=a.ele,n=!1;e(":input",s.form).each(function(){return n?(e(this).focus(),!1):void(this==s&&(n=!0))})}else try{a.ele.focus()}catch(r){}a._closeCalendar()}}),a.isSelected(i)?(t.addClass("selected"),a.settings.selectWeek&&t.parent().addClass("selectedWeek")):a.selectMultiple&&a.numSelected==a.numSelectable&&t.addClass("unselectable")},_applyRenderCallbacks:function(){var t=this;e("td",this.context).each(function(){for(var s=0;s<t.renderCallback.length;s++)$td=e(this),t.renderCallback[s].apply(this,[$td,Date.fromString($td.data("datePickerDate")),t.displayedMonth,t.displayedYear])})},_displayNewMonth:function(t,s,a){return e(t).is(".disabled")||this.setDisplayedMonth(this.displayedMonth+s,this.displayedYear+a,!0),t.blur(),!1},_rerenderCalendar:function(){this._clearCalendar(),this._renderCalendar()},_renderCalendar:function(){if(e("h2",this.context).html(new Date(this.displayedYear,this.displayedMonth,1).asString(e.dpText.HEADER_FORMAT)),e(".dp-calendar",this.context).renderCalendar(e.extend({},this.settings,{month:this.displayedMonth,year:this.displayedYear,renderCallback:this.cellRender,dpController:this,hoverClass:this.hoverClass})),this.displayedYear==this.startDate.getFullYear()&&this.displayedMonth==this.startDate.getMonth()){e(".dp-nav-prev-year",this.context).addClass("disabled"),e(".dp-nav-prev-month",this.context).addClass("disabled"),e(".dp-calendar td.other-month",this.context).each(function(){var t=e(this);Number(t.text())>20&&t.addClass("disabled")});var t=this.startDate.getDate();e(".dp-calendar td.current-month",this.context).each(function(){var s=e(this);Number(s.text())<t&&s.addClass("disabled")})}else{e(".dp-nav-prev-year",this.context).removeClass("disabled"),e(".dp-nav-prev-month",this.context).removeClass("disabled");var t=this.startDate.getDate();if(t>20){var s=this.startDate.getTime(),a=new Date(s);a.addMonths(1),this.displayedYear==a.getFullYear()&&this.displayedMonth==a.getMonth()&&e(".dp-calendar td.other-month",this.context).each(function(){var t=e(this);Date.fromString(t.data("datePickerDate")).getTime()<s&&t.addClass("disabled")})}}if(this.displayedYear==this.endDate.getFullYear()&&this.displayedMonth==this.endDate.getMonth()){e(".dp-nav-next-year",this.context).addClass("disabled"),e(".dp-nav-next-month",this.context).addClass("disabled"),e(".dp-calendar td.other-month",this.context).each(function(){var t=e(this);Number(t.text())<14&&t.addClass("disabled")});var t=this.endDate.getDate();e(".dp-calendar td.current-month",this.context).each(function(){var s=e(this);Number(s.text())>t&&s.addClass("disabled")})}else{e(".dp-nav-next-year",this.context).removeClass("disabled"),e(".dp-nav-next-month",this.context).removeClass("disabled");var t=this.endDate.getDate();if(13>t){var i=new Date(this.endDate.getTime());i.addMonths(-1),this.displayedYear==i.getFullYear()&&this.displayedMonth==i.getMonth()&&e(".dp-calendar td.other-month",this.context).each(function(){var s=e(this),a=Number(s.text());13>a&&a>t&&s.addClass("disabled")})}}this._applyRenderCallbacks()},_closeCalendar:function(t,s){s&&s!=this.ele||(e(document).unbind("mousedown.datepicker"),e(document).unbind("keydown.datepicker"),this._clearCalendar(),e("#dp-popup a").unbind(),e("#dp-popup").empty().remove(),t||e(this.ele).trigger("dpClosed",[this.getSelected()]))},_clearCalendar:function(){e(".dp-calendar td",this.context).unbind(),e(".dp-calendar",this.context).empty()}}),e.dpConst={SHOW_HEADER_NONE:0,SHOW_HEADER_SHORT:1,SHOW_HEADER_LONG:2,POS_TOP:0,POS_BOTTOM:1,POS_LEFT:0,POS_RIGHT:1,POS_CUSTOM:1,DP_INTERNAL_FOCUS:"dpInternalFocusTrigger"},e.dpText={TEXT_PREV_YEAR:"Previous year",TEXT_PREV_MONTH:"Previous month",TEXT_NEXT_YEAR:"Next year",TEXT_NEXT_MONTH:"Next month",TEXT_CLOSE:"Close",TEXT_CHOOSE_DATE:"Choose date",HEADER_FORMAT:"mmmm yyyy"},e.dpVersion="$Id$",e.fn.datePicker.defaults={month:void 0,year:void 0,showHeader:e.dpConst.SHOW_HEADER_SHORT,startDate:void 0,endDate:void 0,inline:!1,renderCallback:null,createButton:!0,showYearNavigation:!0,closeOnSelect:!0,displayClose:!1,selectMultiple:!1,numSelectable:Number.MAX_VALUE,clickInput:!0,rememberViewedMonth:!0,selectWeek:!1,verticalPosition:e.dpConst.POS_CUSTOM,horizontalPosition:e.dpConst.POS_CUSTOM,verticalOffset:0,horizontalOffset:0,hoverClass:"dp-hover",autoFocusNextInput:!1},void 0==e.fn.bgIframe&&(e.fn.bgIframe=function(){return this}),e(window).bind("unload",function(){var t=e.event._dpCache||[];for(var s in t)e(t[s].ele)._dpDestroy()})}(jQuery),Date.dayNames=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],Date.abbrDayNames=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],Date.monthNames=["January","February","March","April","May","June","July","August","September","October","November","December"],Date.abbrMonthNames=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],Date.firstDayOfWeek=1,Date.format="dd-mm-yyyy",Date.fullYearStart="20",function(){function e(e,t){Date.prototype[e]||(Date.prototype[e]=t)}e("isLeapYear",function(){var e=this.getFullYear();return e%4==0&&e%100!=0||e%400==0}),e("isWeekend",function(){return 0==this.getDay()||6==this.getDay()}),e("isWeekDay",function(){return!this.isWeekend()}),e("getDaysInMonth",function(){return[31,this.isLeapYear()?29:28,31,30,31,30,31,31,30,31,30,31][this.getMonth()]}),e("getDayName",function(e){return e?Date.abbrDayNames[this.getDay()]:Date.dayNames[this.getDay()]}),e("getMonthName",function(e){return e?Date.abbrMonthNames[this.getMonth()]:Date.monthNames[this.getMonth()]}),e("getDayOfYear",function(){var e=new Date("1/1/"+this.getFullYear());return Math.floor((this.getTime()-e.getTime())/864e5)}),e("getWeekOfYear",function(){return Math.ceil(this.getDayOfYear()/7)}),e("setDayOfYear",function(e){return this.setMonth(0),this.setDate(e),this}),e("addYears",function(e){return this.setFullYear(this.getFullYear()+e),this}),e("addMonths",function(e){var t=this.getDate();return this.setMonth(this.getMonth()+e),t>this.getDate()&&this.addDays(-this.getDate()),this}),e("addDays",function(e){var t,s=this.getTimezoneOffset();return this.setTime(this.getTime()+864e5*e),t=this.getTimezoneOffset(),t!==s&&this.setTime(this.getTime()+60*(t-s)*1e3),this}),e("addHours",function(e){return this.setHours(this.getHours()+e),this}),e("addMinutes",function(e){return this.setMinutes(this.getMinutes()+e),this}),e("addSeconds",function(e){return this.setSeconds(this.getSeconds()+e),this}),e("zeroTime",function(){return this.setMilliseconds(0),this.setSeconds(0),this.setMinutes(0),this.setHours(0),this}),e("asString",function(e){var s=e||Date.format;return s.split("yyyy").join(this.getFullYear()).split("yy").join((this.getFullYear()+"").substring(2)).split("dd").join(t(this.getDate())).split("d").join(this.getDate()).split("DD").join(this.getDayName(!1)).split("D").join(this.getDayName(!0)).split("mmmm").join(this.getMonthName(!1)).split("mmm").join(this.getMonthName(!0)).split("mm").join(t(this.getMonth()+1)).split("hh").join(t(this.getHours())).split("min").join(t(this.getMinutes())).split("ss").join(t(this.getSeconds()))}),Date.fromString=function(e,t){var s,a,i,n,r,d=t||Date.format,l=new Date("01/01/1977"),o=0;if(s=d.indexOf("mmmm"),s>-1){for(n=0;n<Date.monthNames.length;n++)if(r=e.substr(s,Date.monthNames[n].length),Date.monthNames[n]==r){o=Date.monthNames[n].length-4;break}l.setMonth(n)}else if(s=d.indexOf("mmm"),s>-1){for(r=e.substr(s,3),n=0;n<Date.abbrMonthNames.length&&Date.abbrMonthNames[n]!=r;n++);l.setMonth(n)}else l.setMonth(Number(e.substr(d.indexOf("mm"),2))-1);return i=d.indexOf("yyyy"),i>-1?(i>s&&(i+=o),l.setFullYear(Number(e.substr(i,4)))):(i>s&&(i+=o),l.setFullYear(Number(Date.fullYearStart+e.substr(d.indexOf("yy"),2)))),a=d.indexOf("dd"),a>s&&(a+=o),l.setDate(Number(e.substr(a,2))),isNaN(l.getTime())?!1:l};var t=function(e){var t="0"+e;return t.substring(t.length-2)}}();